sso_2.0.0

This commit is contained in:
lalitdeore
2024-10-04 13:17:52 +05:30
parent f2a0aac31d
commit acc039623f
4 changed files with 627 additions and 444 deletions
+3 -3
View File
@@ -1131,9 +1131,9 @@ func checkAdminLogin(resp http.ResponseWriter, request *http.Request) {
} }
// No childorg setup, only parent org // No childorg setup, only parent org
if len(org.ManagerOrgs) > 0 || len(org.CreatorOrg) > 0 { // if len(org.ManagerOrgs) > 0 || len(org.CreatorOrg) > 0 {
continue // continue
} // }
// Should run calculations // Should run calculations
if len(org.SSOConfig.OpenIdAuthorization) > 0 { if len(org.SSOConfig.OpenIdAuthorization) > 0 {
+61 -30
View File
@@ -42,6 +42,7 @@ import {
Delete, Delete,
RestaurantRounded, RestaurantRounded,
Cloud, Cloud,
CheckCircle
} from "@mui/icons-material"; } from "@mui/icons-material";
//import { useAlert //import { useAlert
@@ -71,6 +72,7 @@ const Billing = (props) => {
const [currentAppRunsInNumber, setCurrentAppRunsInNumber] = useState(0); const [currentAppRunsInNumber, setCurrentAppRunsInNumber] = useState(0);
const [alertThresholds, setAlertThresholds] = useState(selectedOrganization.Billing !== undefined && selectedOrganization.Billing.AlertThreshold !== undefined && selectedOrganization.Billing.AlertThreshold !== null ? selectedOrganization.Billing.AlertThreshold : [{ percentage: '', count: '', Email_send: false }]); const [alertThresholds, setAlertThresholds] = useState(selectedOrganization.Billing !== undefined && selectedOrganization.Billing.AlertThreshold !== undefined && selectedOrganization.Billing.AlertThreshold !== null ? selectedOrganization.Billing.AlertThreshold : [{ percentage: '', count: '', Email_send: false }]);
const [currentIndex, setCurrentIndex] = useState(0); const [currentIndex, setCurrentIndex] = useState(0);
const [deleteAlertVerification, setDeleteAlertVerification] = useState(false);
useEffect(() => { useEffect(() => {
if (userdata.app_execution_limit !== undefined && userdata.app_execution_usage !== undefined) { if (userdata.app_execution_limit !== undefined && userdata.app_execution_usage !== undefined) {
@@ -353,13 +355,13 @@ const Billing = (props) => {
if (subscription.name === "Enterprise" && subscription.active === true) { if (subscription.name === "Enterprise" && subscription.active === true) {
top_text = "Current Plan" top_text = "Current Plan"
newPaperstyle.border = "1px solid #f85a3e" // newPaperstyle.border = "1px solid #f85a3e"
} }
var showSupport = false var showSupport = false
if (subscription.name.includes("default")) { if (subscription.name.includes("default")) {
top_text = "Custom Contract" top_text = "Custom Contract"
newPaperstyle.border = "1px solid #f85a3e" newPaperstyle.border = "1px solid rgba(255,255,255,0.3)"
showSupport = true showSupport = true
} }
@@ -379,7 +381,7 @@ const Billing = (props) => {
if (highlight === true) { if (highlight === true) {
// Add an "Upgrade now" button // Add an "Upgrade now" button
newPaperstyle.border = "1px solid #f85a3e" newPaperstyle.border = "1px solid rgba(255,255,255,0.3)"
} }
if (hovered) { if (hovered) {
@@ -820,7 +822,8 @@ const Billing = (props) => {
height: 40, height: 40,
fontSize: 16, fontSize: 16,
color: "white", color: "white",
backgroundImage: userdata.has_card_available ? null : "linear-gradient(to right, #f86a3e, #f34079)", backgroundColor: userdata.has_card_available ? null : "#f86743",
// backgroundImage: userdata.has_card_available ? null : "linear-gradient(to right, #f86a3e, #f34079)",
textTransform: "none", textTransform: "none",
}} }}
@@ -852,7 +855,7 @@ const Billing = (props) => {
height: 40, height: 40,
fontSize: 16, fontSize: 16,
color: "white", color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)", backgroundColor: "#f86743",
textTransform: 'none' textTransform: 'none'
}} }}
onClick={() => { onClick={() => {
@@ -1036,11 +1039,11 @@ const Billing = (props) => {
<Paper style={{ <Paper style={{
padding: 20, padding: 20,
// maxWidth: 400, // maxWidth: 400,
minWidth: 340, width: 340,
height: 480, height: 480,
backgroundColor: hovered ? "#232427" : theme.palette.platformColor, backgroundColor: hovered ? "#232427" : theme.palette.platformColor,
borderRadius: theme.palette.borderRadius * 2, borderRadius: theme.palette.borderRadius * 2,
border: "1px solid #f85a3e", border: "1px solid rgba(255,255,255,0.3)",
marginRight: 10, marginRight: 10,
marginTop: 15, marginTop: 15,
}} }}
@@ -1133,8 +1136,8 @@ const Billing = (props) => {
height: 40, height: 40,
fontSize: 16, fontSize: 16,
color: "white", color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)", backgroundColor: "#f86743",
textTransform: 'none' textTransform: 'none',
}} }}
onClick={() => { onClick={() => {
if (Cloud) { if (Cloud) {
@@ -1188,7 +1191,7 @@ const Billing = (props) => {
height: 40, height: 40,
fontSize: 16, fontSize: 16,
color: "white", color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)", backgroundColor: "#f86743",
textTransform: 'none', textTransform: 'none',
cursor: getProfessionalServices ? 'pointer' : 'not-allowed', cursor: getProfessionalServices ? 'pointer' : 'not-allowed',
opacity: getProfessionalServices ? 1 : 0.6, opacity: getProfessionalServices ? 1 : 0.6,
@@ -1315,7 +1318,7 @@ const Billing = (props) => {
width: 340, width: 340,
backgroundColor: hovered ? "#232427" : theme.palette.platformColor, backgroundColor: hovered ? "#232427" : theme.palette.platformColor,
borderRadius: theme.palette.borderRadius * 2, borderRadius: theme.palette.borderRadius * 2,
border: "1px solid #f85a3e", border: "1px solid rgba(255,255,255,0.3)",
marginRight: 10, marginRight: 10,
marginTop: 15, marginTop: 15,
}} }}
@@ -1373,7 +1376,7 @@ const Billing = (props) => {
height: 40, height: 40,
fontSize: 16, fontSize: 16,
color: "white", color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)", backgroundColor: "#f86743",
textTransform: 'none' textTransform: 'none'
}} }}
onClick={() => { onClick={() => {
@@ -1381,6 +1384,8 @@ const Billing = (props) => {
ReactGA.event({ ReactGA.event({
category: "Billing", category: "Billing",
action: "click_public_training_button", action: "click_public_training_button",
label: "Public Training",
userId: userdata?.id
}); });
} }
navigate("/training") navigate("/training")
@@ -1399,21 +1404,24 @@ const Billing = (props) => {
height: 40, height: 40,
fontSize: 16, fontSize: 16,
color: "white", color: "white",
backgroundImage: "linear-gradient(to right, #f86a3e, #f34079)", backgroundColor: "#f86743",
textTransform: 'none' textTransform: 'none'
}} }}
onClick={() => { onClick={() => {
if (Cloud) { if (Cloud) {
ReactGA.event({ ReactGA.event({
category: "Billing", category: "Billing",
action: "click_public_training_button", action: "click_private_training_button",
label: "Private Training",
userId: userdata?.id,
}); });
} }
setOpenPrivateTraining(true) setOpenPrivateTraining(true);
}} }}
> >
Private Training Private Training
</Button> </Button>
<Dialog open={openPrivateTraining} <Dialog open={openPrivateTraining}
onClose={() => setOpenPrivateTraining(false)} onClose={() => setOpenPrivateTraining(false)}
fullWidth fullWidth
@@ -1818,6 +1826,7 @@ const Billing = (props) => {
// Update currentIndex based on remaining elements // Update currentIndex based on remaining elements
const findCurrentIndex = newAlertThresholds.some(threshold => threshold.Email_send === false); const findCurrentIndex = newAlertThresholds.some(threshold => threshold.Email_send === false);
setCurrentIndex(findCurrentIndex ? newAlertThresholds.findIndex(threshold => threshold.Email_send === false) : - 1); setCurrentIndex(findCurrentIndex ? newAlertThresholds.findIndex(threshold => threshold.Email_send === false) : - 1);
toast.info("Alert Threshold deleted successfully. Don't forget to save your changes.");
}; };
const HandleEditOrgForAlertThreshold = (orgId) => { const HandleEditOrgForAlertThreshold = (orgId) => {
@@ -1997,15 +2006,6 @@ const Billing = (props) => {
/> />
</span> </span>
: null} : null}
{isCloud && billingInfo.subscription !== undefined && billingInfo.subscription !== null ? isChildOrg ? null :
<ConsultationManagement
globalUrl={globalUrl}
userdata={userdata}
selectedOrganization={selectedOrganization}
/> : null}
<TrainingService />
{isCloud && {isCloud &&
selectedOrganization.subscriptions !== undefined && selectedOrganization.subscriptions !== undefined &&
@@ -2261,7 +2261,29 @@ const Billing = (props) => {
</div> </div>
) : null*/} ) : null*/}
<div style={{ marginTop: 20, marginLeft: 10 }}> {!isChildOrg && isCloud && (
<div style={{ display: 'flex', flexDirection: 'column', marginTop: 10 }}>
<Typography style={{ marginBottom: 5 }} variant="h4">
Professional Services
</Typography>
<Typography color="textSecondary">
We offer priority support through consultations and training to help you make the most of our product. If you have any questions, please reach out to us at support@shuffler.io.
</Typography>
<div style={{ display: 'flex', flexDirection: 'row', marginTop: 5 }}>
{billingInfo.subscription !== undefined && billingInfo.subscription !== null ? (
isChildOrg ? null : (
<ConsultationManagement
globalUrl={globalUrl}
userdata={userdata}
selectedOrganization={selectedOrganization}
/>
)
) : null}
<TrainingService />
</div>
</div>
)}
<div style={{ marginTop: isCloud && 40, marginLeft: 10 }}>
<Typography <Typography
style={{ marginBottom: 5 }} style={{ marginBottom: 5 }}
variant="h4" variant="h4"
@@ -2303,7 +2325,9 @@ const Billing = (props) => {
: " " + 0 + " "} : " " + 0 + " "}
app runs. app runs.
</Typography> </Typography>
<Typography variant="body1" color="textSecondary" style={{ marginTop: 10 }}>
Please note: Once your app runs reach the set alert threshold, all admins in the organization will receive an email notification.
</Typography>
<div style={{ marginTop: 15 }}> <div style={{ marginTop: 15 }}>
{alertThresholds.map((threshold, index) => ( {alertThresholds.map((threshold, index) => (
<div key={index} style={{ display: 'flex', alignItems: 'center' }}> <div key={index} style={{ display: 'flex', alignItems: 'center' }}>
@@ -2354,6 +2378,7 @@ const Billing = (props) => {
margin="normal" margin="normal"
variant="outlined" variant="outlined"
/> />
<span style={{ marginLeft: alertThresholds[index].Email_send === true ? 10 : 35, color: 'green' }}>{alertThresholds[index].Email_send === true && <Tooltip title="We have already sent alert for this threshold."><CheckCircle /></Tooltip>}</span>
{ {
alertThresholds.length > 1 && alertThresholds.length > 1 &&
( (
@@ -2362,18 +2387,24 @@ const Billing = (props) => {
disableElevation disableElevation
sx={{ sx={{
padding: 0, padding: 0,
color: 'red',
'&:hover': { '&:hover': {
backgroundColor: 'transparent', backgroundColor: 'transparent',
}, },
}} }}
onClick={() => { handleDeleteAlertThreshold(index) }} onClick={() => { setDeleteAlertVerification(true) }}
> >
<DeleteIcon /> <DeleteIcon sx={{ color: theme.palette.secondary.main }} />
</Button> </Button>
) )
} }
<Dialog open={deleteAlertVerification} onClose={() => setDeleteAlertVerification(false)} sx={{ '& .MuiBackdrop-root': { backgroundColor: 'rgba(0, 0, 0, 0.3)', }, }}>
<DialogTitle>Are you sure you want to delete this threshold?</DialogTitle>
<DialogActions>
<Button style={{ textTransform: 'none', fontSize: 16 }} color="primary" onClick={() => setDeleteAlertVerification(false)}>Cancel</Button>
<Button style={{ textTransform: 'none', fontSize: 16 }} color="secondary" onClick={() => { handleDeleteAlertThreshold(index); setDeleteAlertVerification(false) }} >Delete</Button>
</DialogActions>
</Dialog>
</div> </div>
))} ))}
</div> </div>
@@ -2415,4 +2446,4 @@ const Billing = (props) => {
) )
} }
export default Billing; export default Billing;
+25 -13
View File
@@ -296,38 +296,50 @@ const Header = (props) => {
if (response.status !== 200) { if (response.status !== 200) {
console.log("Error in response"); console.log("Error in response");
} else { } else {
localStorage.removeItem("apps") localStorage.removeItem("apps");
localStorage.removeItem("workflows") localStorage.removeItem("workflows");
localStorage.removeItem("userinfo") localStorage.removeItem("userinfo");
} }
return response.json(); return response.json();
}) })
.then(function (responseJson) { .then(function (responseJson) {
console.log("In here?") console.log("In here?");
if (responseJson.success === true) { if (responseJson.success === true) {
if (responseJson.region_url !== undefined && responseJson.region_url !== null && responseJson.region_url.length > 0) { if (
responseJson.region_url !== undefined &&
responseJson.region_url !== null &&
responseJson.region_url.length > 0
) {
console.log("Region Change: ", responseJson.region_url); console.log("Region Change: ", responseJson.region_url);
localStorage.setItem("globalUrl", responseJson.region_url); localStorage.setItem("globalUrl", responseJson.region_url);
//globalUrl = responseJson.region_url //globalUrl = responseJson.region_url
} }
if (responseJson["reason"] === "SSO_REDIRECT") { if (responseJson["reason"] === "SSO_REDIRECT") {
setTimeout(() => { setTimeout(() => {
toast.info("Redirecting to SSO login page as SSO is required for this organization.") toast.info(
window.location.href = responseJson["url"] "Redirecting to SSO login page as SSO is required for this organization."
return );
}, 2000) window.location.href = responseJson["url"];
return;
}, 2000);
} else { } else {
toast("Successfully changed active organization - refreshing!");
setTimeout(() => { setTimeout(() => {
window.location.reload() window.location.reload();
}, 2000); }, 2000);
} }
toast("Successfully changed active organization - refreshing!");
} else { } else {
if (responseJson.reason !== undefined && responseJson.reason !== null && responseJson.reason.length > 0) { if (
responseJson.reason !== undefined &&
responseJson.reason !== null &&
responseJson.reason.length > 0
) {
toast(responseJson.reason); toast(responseJson.reason);
} else { } else {
toast("Failed changing org. Try again or contact support@shuffler.io if this persists."); toast(
"Failed changing org. Try again or contact support@shuffler.io if this persists."
);
} }
} }
}) })
+538 -398
View File
@@ -319,9 +319,71 @@ const OrgHeaderexpanded = (props) => {
</Tooltip> </Tooltip>
); );
const toggleBetweenRequiredOrOptional = (event) => { const toggleBetweenRequiredOrOptional = (event) => {
setSSORequired(event.target.checked); if (
}; ssoEntrypoint === "" &&
openidAuthorization === "" &&
openidToken === ""
) {
if (!SSORequired) {
toast.error(
"Please fill in fields for either OpenID connect or SSO before continuing. "
);
return;
}
} else {
toast.info("Toggled SSO. Remember to save.");
}
setSSORequired(event.target.checked);
};
const HandleTestSSO = () => {
const url = `${globalUrl}/api/v1/orgs/${selectedOrganization?.id}/change`;
const data = {
org_id: selectedOrganization?.id,
sso_test: true,
};
fetch(url, {
mode: "cors",
credentials: "include",
crossDomain: true,
method: "POST",
body: JSON.stringify(data),
withCredentials: true,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
})
.then((response) => {
if (response.status !== 200) {
toast.error(
"Failed to test sso. Please try again later or contact support@shuffler.io if issue persist."
);
return;
}
return response.json();
})
.then((responjson) => {
if (responjson["reason"] === "SSO_REDIRECT") {
setTimeout(() => {
toast.info(
"Redirecting to SSO login page as SSO is required for this organization."
);
window.location.href = responjson["url"];
return;
}, 2000);
} else {
toast.error(
"No SSO found for this org. Please set up sso for this org."
);
}
})
.catch((err) => {
console.log("error for sso test is: ", err);
});
};
return ( return (
<div style={{ textAlign: "center" }}> <div style={{ textAlign: "center" }}>
@@ -664,398 +726,476 @@ const OrgHeaderexpanded = (props) => {
SSO Configuration SSO Configuration
</Typography> </Typography>
<div style={{ display: 'flex', flexDirection: 'column', marginLeft: 10, width: '100%', }}> <div
<Typography variant="body2" color="textSecondary" style={{ margin: '5px 0px 5px 10px' }}>Make SAML SSO or OpenID Authentication Required or Optional for Your Organization.</Typography> style={{
<div> display: "flex",
<Switch flexDirection: "column",
checked={SSORequired} marginLeft: 10,
onChange={toggleBetweenRequiredOrOptional} width: "100%",
name="onOffSwitch" }}
color="primary" >
title="Make SAML SSO or OpenID Authentication Required or Optional for Your Organization" <Typography
/> variant="body2"
{SSORequired ? 'Required' : 'Optional'} color="textSecondary"
</div> style={{ margin: "5px 0px 5px 10px" }}
</div> >
<Grid item xs={12} style={{}}> Make SAML SSO or OpenID Authentication Required or Optional for Your
<Typography variant="h6" style={{ textAlign: "center", }}>OpenID connect</Typography> Organization.
<Grid container style={{ marginTop: 10, }}> </Typography>
<Grid item xs={6} style={{}}> <div>
<span> <Switch
<Typography>Client ID</Typography> checked={SSORequired}
<TextField onChange={toggleBetweenRequiredOrOptional}
required name="onOffSwitch"
style={{ color="primary"
flex: "1", title="Make SAML SSO or OpenID Authentication Required or Optional for Your Organization"
marginTop: "5px", />
marginRight: "15px", {SSORequired ? "Required" : "Optional"}
backgroundColor: theme.palette.inputColor, </div>
}} </div>
fullWidth={true} <div
type="name" style={{
multiline={true} display: "flex",
rows={2} flexDirection: "column",
disabled={ marginTop: 20,
selectedOrganization.manager_orgs !== undefined && marginLeft: 10,
selectedOrganization.manager_orgs !== null && width: "100%",
selectedOrganization.manager_orgs.length > 0 borderBottom: "1px solid #414347",
} paddingBottom: 10,
id="outlined-with-placeholder" }}
margin="normal" >
variant="outlined" <Typography variant="body1" style={{ margin: "5px 0px 5px 10px" }}>
placeholder="The OpenID client ID from the identity provider" You can test your SSO configuration by clicking the button below.
value={openidClientId} Before testing, ensure you have set Open ID Connect or SAML SSO
onChange={(e) => { credentials.
setOpenidClientId(e.target.value); </Typography>
}} <Tooltip
InputProps={{ title={
classes: { !(
notchedOutline: classes.notchedOutline, ssoEntrypoint.length > 0 ||
}, ssoCertificate.length > 0 ||
style: { openidAuthorization.length > 0 ||
color: "white", openidClientId.length > 0
}, )
}} ? "Please ensure all SSO credentials are set before testing."
/> : ""
</span> }
</Grid> >
<Grid item xs={6} style={{}}> <span style={{ width: 100 }}>
<span> <Button
<Typography>Client Secret (optional)</Typography> variant="outlined"
<TextField color="primary"
required style={{ width: 100, textTransform: "none", margin: 10 }}
style={{ disabled={
flex: "1", !(
marginTop: "5px", ssoEntrypoint.length > 0 ||
marginRight: "15px", ssoCertificate.length > 0 ||
backgroundColor: theme.palette.inputColor, openidAuthorization.length > 0 ||
}} openidClientId.length > 0
fullWidth={true} )
type="name" }
multiline={true} onClick={HandleTestSSO}
rows={2} >
disabled={ Test SSO
selectedOrganization.manager_orgs !== undefined && </Button>
selectedOrganization.manager_orgs !== null && </span>
selectedOrganization.manager_orgs.length > 0 </Tooltip>
} </div>
id="outlined-with-placeholder" <div></div>
margin="normal" <Grid item xs={12} style={{}}>
variant="outlined" <Typography variant="h6" style={{ textAlign: "center" }}>
placeholder="The OpenID client secret - DONT use this if dealing with implicit auth / PKCE" OpenID connect
value={openidClientSecret} </Typography>
onChange={(e) => { <Grid container style={{ marginTop: 10 }}>
setOpenidClientSecret(e.target.value); <Grid item xs={6} style={{}}>
}} <span>
InputProps={{ <Typography>Client ID</Typography>
classes: { <TextField
notchedOutline: classes.notchedOutline, required
}, style={{
style: { flex: "1",
color: "white", marginTop: "5px",
}, marginRight: "15px",
}} backgroundColor: theme.palette.inputColor,
/> }}
</span> fullWidth={true}
</Grid> type="name"
</Grid> multiline={true}
<Grid container style={{ marginTop: 10, }}> rows={2}
<Grid item xs={6} style={{}}> disabled={
<span> selectedOrganization.manager_orgs !== undefined &&
<Typography>Authorization URL</Typography> selectedOrganization.manager_orgs !== null &&
<TextField selectedOrganization.manager_orgs.length > 0
required }
style={{ id="outlined-with-placeholder"
flex: "1", margin="normal"
marginTop: "5px", variant="outlined"
marginRight: "15px", placeholder="The OpenID client ID from the identity provider"
backgroundColor: theme.palette.inputColor, value={openidClientId}
}} onChange={(e) => {
fullWidth={true} setOpenidClientId(e.target.value);
type="name" }}
id="outlined-with-placeholder" InputProps={{
margin="normal" classes: {
variant="outlined" notchedOutline: classes.notchedOutline,
multiline={true} },
rows={2} style: {
placeholder="The OpenID authorization URL (usually ends with /authorize)" color: "white",
value={openidAuthorization} },
onChange={(e) => { }}
setOpenidAuthorization(e.target.value) />
}} </span>
InputProps={{ </Grid>
classes: { <Grid item xs={6} style={{}}>
notchedOutline: classes.notchedOutline, <span>
}, <Typography>Client Secret (optional)</Typography>
style: { <TextField
color: "white", required
}, style={{
}} flex: "1",
/> marginTop: "5px",
</span> marginRight: "15px",
</Grid> backgroundColor: theme.palette.inputColor,
<Grid item xs={6} style={{}}> }}
<span> fullWidth={true}
<Typography>Token URL</Typography> type="name"
<TextField multiline={true}
required rows={2}
style={{ disabled={
flex: "1", selectedOrganization.manager_orgs !== undefined &&
marginTop: "5px", selectedOrganization.manager_orgs !== null &&
marginRight: "15px", selectedOrganization.manager_orgs.length > 0
backgroundColor: theme.palette.inputColor, }
}} id="outlined-with-placeholder"
fullWidth={true} margin="normal"
type="name" variant="outlined"
id="outlined-with-placeholder" placeholder="The OpenID client secret - DONT use this if dealing with implicit auth / PKCE"
margin="normal" value={openidClientSecret}
variant="outlined" onChange={(e) => {
multiline={true} setOpenidClientSecret(e.target.value);
rows={2} }}
placeholder="The OpenID token URL (usually ends with /token)" InputProps={{
value={openidToken} classes: {
onChange={(e) => { notchedOutline: classes.notchedOutline,
setOpenidToken(e.target.value) },
}} style: {
InputProps={{ color: "white",
classes: { },
notchedOutline: classes.notchedOutline, }}
}, />
style: { </span>
color: "white", </Grid>
}, </Grid>
}} <Grid container style={{ marginTop: 10 }}>
/> <Grid item xs={6} style={{}}>
</span> <span>
</Grid> <Typography>Authorization URL</Typography>
</Grid> <TextField
</Grid> required
{/* } */} style={{
{/*isCloud ? null : */} flex: "1",
<Grid item xs={12} style={{ marginTop: 50, }}> marginTop: "5px",
<Typography variant="h6" style={{ textAlign: "center", }}>SAML SSO (v1.1)</Typography> marginRight: "15px",
<Grid container style={{ marginTop: 20, }}> backgroundColor: theme.palette.inputColor,
<Grid item xs={6} style={{}}> }}
<span> fullWidth={true}
<Typography>SSO Entrypoint (IdP)</Typography> type="name"
<TextField id="outlined-with-placeholder"
required margin="normal"
style={{ variant="outlined"
flex: "1", multiline={true}
marginTop: "5px", rows={2}
marginRight: "15px", placeholder="The OpenID authorization URL (usually ends with /authorize)"
backgroundColor: theme.palette.inputColor, value={openidAuthorization}
}} onChange={(e) => {
fullWidth={true} setOpenidAuthorization(e.target.value);
type="name" }}
multiline={true} InputProps={{
rows={2} classes: {
disabled={ notchedOutline: classes.notchedOutline,
selectedOrganization.manager_orgs !== undefined && },
selectedOrganization.manager_orgs !== null && style: {
selectedOrganization.manager_orgs.length > 0 color: "white",
} },
id="outlined-with-placeholder" }}
margin="normal" />
variant="outlined" </span>
placeholder="The entrypoint URL from your provider" </Grid>
value={ssoEntrypoint} <Grid item xs={6} style={{}}>
onChange={(e) => { <span>
setSsoEntrypoint(e.target.value); <Typography>Token URL</Typography>
}} <TextField
InputProps={{ required
classes: { style={{
notchedOutline: classes.notchedOutline, flex: "1",
}, marginTop: "5px",
style: { marginRight: "15px",
color: "white", backgroundColor: theme.palette.inputColor,
}, }}
}} fullWidth={true}
/> type="name"
</span> id="outlined-with-placeholder"
</Grid> margin="normal"
<Grid item xs={6} style={{}}> variant="outlined"
<span> multiline={true}
<Typography>SSO Certificate (X509)</Typography> rows={2}
<TextField placeholder="The OpenID token URL (usually ends with /token)"
required value={openidToken}
style={{ onChange={(e) => {
flex: "1", setOpenidToken(e.target.value);
marginTop: "5px", }}
marginRight: "15px", InputProps={{
backgroundColor: theme.palette.inputColor, classes: {
}} notchedOutline: classes.notchedOutline,
fullWidth={true} },
type="name" style: {
id="outlined-with-placeholder" color: "white",
margin="normal" },
variant="outlined" }}
multiline={true} />
rows={2} </span>
placeholder="The X509 certificate to use" </Grid>
value={ssoCertificate} </Grid>
onChange={(e) => { </Grid>
setSsoCertificate(e.target.value); {/* } */}
}} {/*isCloud ? null : */}
InputProps={{ <Grid item xs={12} style={{ marginTop: 50 }}>
classes: { <Typography variant="h6" style={{ textAlign: "center" }}>
notchedOutline: classes.notchedOutline, SAML SSO (v1.1)
}, </Typography>
style: { <Grid container style={{ marginTop: 20 }}>
color: "white", <Grid item xs={6} style={{}}>
}, <span>
}} <Typography>SSO Entrypoint (IdP)</Typography>
/> <TextField
</span> required
</Grid> style={{
</Grid> flex: "1",
{isCloud ? marginTop: "5px",
<Typography variant="body2" style={{ textAlign: "left", }} color="textSecondary"> marginRight: "15px",
IdP URL for Shuffle: https://shuffler.io/api/v1/login_sso backgroundColor: theme.palette.inputColor,
</Typography> }}
: null} fullWidth={true}
</Grid> type="name"
{isCloud ? null : ( multiline={true}
<Grid item xs={6} style={{}}> rows={2}
<span> disabled={
<Typography>App Download URL</Typography> selectedOrganization.manager_orgs !== undefined &&
<TextField selectedOrganization.manager_orgs !== null &&
required selectedOrganization.manager_orgs.length > 0
style={{ }
flex: "1", id="outlined-with-placeholder"
marginTop: "5px", margin="normal"
marginRight: "15px", variant="outlined"
backgroundColor: theme.palette.inputColor, placeholder="The entrypoint URL from your provider"
}} value={ssoEntrypoint}
fullWidth={true} onChange={(e) => {
type="name" setSsoEntrypoint(e.target.value);
id="outlined-with-placeholder" }}
margin="normal" InputProps={{
variant="outlined" classes: {
placeholder="A description for the organization" notchedOutline: classes.notchedOutline,
value={appDownloadUrl} },
onChange={(e) => { style: {
setAppDownloadUrl(e.target.value); color: "white",
}} },
InputProps={{ }}
classes: { />
notchedOutline: classes.notchedOutline, </span>
}, </Grid>
style: { <Grid item xs={6} style={{}}>
color: "white", <span>
}, <Typography>SSO Certificate (X509)</Typography>
}} <TextField
/> required
</span> style={{
</Grid> flex: "1",
)} marginTop: "5px",
{isCloud ? null : ( marginRight: "15px",
<Grid item xs={6} style={{}}> backgroundColor: theme.palette.inputColor,
<span> }}
<Typography>App Download Branch</Typography> fullWidth={true}
<TextField type="name"
required id="outlined-with-placeholder"
style={{ margin="normal"
flex: "1", variant="outlined"
marginTop: "5px", multiline={true}
marginRight: "15px", rows={2}
backgroundColor: theme.palette.inputColor, placeholder="The X509 certificate to use"
}} value={ssoCertificate}
fullWidth={true} onChange={(e) => {
type="name" setSsoCertificate(e.target.value);
id="outlined-with-placeholder" }}
margin="normal" InputProps={{
variant="outlined" classes: {
placeholder="A description for the organization" notchedOutline: classes.notchedOutline,
value={appDownloadBranch} },
onChange={(e) => { style: {
setAppDownloadBranch(e.target.value); color: "white",
}} },
InputProps={{ }}
classes: { />
notchedOutline: classes.notchedOutline, </span>
}, </Grid>
style: { </Grid>
color: "white", {isCloud ? (
}, <Typography
}} variant="body2"
/> style={{ textAlign: "left" }}
</span> color="textSecondary"
</Grid> >
)} IdP URL for Shuffle: https://shuffler.io/api/v1/login_sso
{isCloud ? null : ( </Typography>
<Grid item xs={6} style={{}}> ) : null}
<span> </Grid>
<Typography>Workflow Download URL</Typography> {isCloud ? null : (
<TextField <Grid item xs={6} style={{}}>
required <span>
style={{ <Typography>App Download URL</Typography>
flex: "1", <TextField
marginTop: "5px", required
marginRight: "15px", style={{
backgroundColor: theme.palette.inputColor, flex: "1",
}} marginTop: "5px",
fullWidth={true} marginRight: "15px",
type="name" backgroundColor: theme.palette.inputColor,
id="outlined-with-placeholder" }}
margin="normal" fullWidth={true}
variant="outlined" type="name"
placeholder="A description for the organization" id="outlined-with-placeholder"
value={workflowDownloadUrl} margin="normal"
onChange={(e) => { variant="outlined"
setWorkflowDownloadUrl(e.target.value); placeholder="A description for the organization"
}} value={appDownloadUrl}
InputProps={{ onChange={(e) => {
classes: { setAppDownloadUrl(e.target.value);
notchedOutline: classes.notchedOutline, }}
}, InputProps={{
style: { classes: {
color: "white", notchedOutline: classes.notchedOutline,
}, },
}} style: {
/> color: "white",
</span> },
</Grid> }}
)} />
{isCloud ? null : ( </span>
<Grid item xs={6} style={{}}> </Grid>
<span> )}
<Typography>Workflow Download Branch</Typography> {isCloud ? null : (
<TextField <Grid item xs={6} style={{}}>
required <span>
style={{ <Typography>App Download Branch</Typography>
flex: "1", <TextField
marginTop: "5px", required
marginRight: "15px", style={{
backgroundColor: theme.palette.inputColor, flex: "1",
}} marginTop: "5px",
fullWidth={true} marginRight: "15px",
type="name" backgroundColor: theme.palette.inputColor,
id="outlined-with-placeholder" }}
margin="normal" fullWidth={true}
variant="outlined" type="name"
placeholder="A description for the organization" id="outlined-with-placeholder"
value={workflowDownloadBranch} margin="normal"
onChange={(e) => { variant="outlined"
setWorkflowDownloadBranch(e.target.value); placeholder="A description for the organization"
}} value={appDownloadBranch}
InputProps={{ onChange={(e) => {
classes: { setAppDownloadBranch(e.target.value);
notchedOutline: classes.notchedOutline, }}
}, InputProps={{
style: { classes: {
color: "white", notchedOutline: classes.notchedOutline,
}, },
}} style: {
/> color: "white",
</span> },
</Grid> }}
)} />
</span>
</Grid>
)}
{isCloud ? null : (
<Grid item xs={6} style={{}}>
<span>
<Typography>Workflow Download URL</Typography>
<TextField
required
style={{
flex: "1",
marginTop: "5px",
marginRight: "15px",
backgroundColor: theme.palette.inputColor,
}}
fullWidth={true}
type="name"
id="outlined-with-placeholder"
margin="normal"
variant="outlined"
placeholder="A description for the organization"
value={workflowDownloadUrl}
onChange={(e) => {
setWorkflowDownloadUrl(e.target.value);
}}
InputProps={{
classes: {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
},
}}
/>
</span>
</Grid>
)}
{isCloud ? null : (
<Grid item xs={6} style={{}}>
<span>
<Typography>Workflow Download Branch</Typography>
<TextField
required
style={{
flex: "1",
marginTop: "5px",
marginRight: "15px",
backgroundColor: theme.palette.inputColor,
}}
fullWidth={true}
type="name"
id="outlined-with-placeholder"
margin="normal"
variant="outlined"
placeholder="A description for the organization"
value={workflowDownloadBranch}
onChange={(e) => {
setWorkflowDownloadBranch(e.target.value);
}}
InputProps={{
classes: {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
},
}}
/>
</span>
</Grid>
)}
<div style={{ margin: "auto", textalign: "center", marginTop: 15, marginBottom: 15, }}> <div
{orgSaveButton} style={{
</div> margin: "auto",
{/* textalign: "center",
marginTop: 15,
marginBottom: 15,
}}
>
{orgSaveButton}
</div>
{/*
<span style={{textAlign: "center"}}> <span style={{textAlign: "center"}}>
{expanded ? {expanded ?
<ExpandLessIcon /> <ExpandLessIcon />
@@ -1064,9 +1204,9 @@ const OrgHeaderexpanded = (props) => {
} }
</span> </span>
*/} */}
</Grid> </Grid>
</div> </div>
) );
} };
export default OrgHeaderexpanded; export default OrgHeaderexpanded;