App framework fixes and new ways to get usecases
This commit is contained in:
@@ -263,7 +263,7 @@ func handleGetWorkflowqueue(resp http.ResponseWriter, request *http.Request) {
|
|||||||
|
|
||||||
environment := request.Header.Get("org")
|
environment := request.Header.Get("org")
|
||||||
if len(environment) == 0 {
|
if len(environment) == 0 {
|
||||||
log.Printf("[AUDIT] No 'org' header set (get workflow queue). Required for cloud.")
|
//log.Printf("[AUDIT] No 'org' header set (get workflow queue). ")
|
||||||
/*
|
/*
|
||||||
resp.WriteHeader(403)
|
resp.WriteHeader(403)
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Specify the org header. This can be done by setting the 'ORG' environment variable for Orborus to your Org ID in Shuffle"}`)))
|
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Specify the org header. This can be done by setting the 'ORG' environment variable for Orborus to your Org ID in Shuffle"}`)))
|
||||||
@@ -276,7 +276,7 @@ func handleGetWorkflowqueue(resp http.ResponseWriter, request *http.Request) {
|
|||||||
// This section is cloud custom for now
|
// This section is cloud custom for now
|
||||||
auth := request.Header.Get("Authorization")
|
auth := request.Header.Get("Authorization")
|
||||||
if len(auth) == 0 {
|
if len(auth) == 0 {
|
||||||
log.Printf("[AUDIT] No Authorization header set. Required for cloud. Env: %s, org: %s", orgId, environment)
|
//log.Printf("[AUDIT] No Authorization header set. Env: %s, org: %s", orgId, environment)
|
||||||
/*
|
/*
|
||||||
resp.WriteHeader(401)
|
resp.WriteHeader(401)
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Specify the auth header (only applicable for cloud for now)."}`)))
|
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Specify the auth header (only applicable for cloud for now)."}`)))
|
||||||
|
|||||||
@@ -116,58 +116,7 @@ export const usecases = {
|
|||||||
"human": true,
|
"human": true,
|
||||||
},
|
},
|
||||||
]},
|
]},
|
||||||
"Ransomware": {
|
|
||||||
"manual": [],
|
|
||||||
"automated": [
|
|
||||||
{
|
|
||||||
"source": "BOTTOM_LEFT",
|
|
||||||
"target": "EDR & AV",
|
|
||||||
"description": "EDR & AV alert",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "EDR & AV",
|
|
||||||
"target": "SHUFFLE",
|
|
||||||
"description": "",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "SHUFFLE",
|
|
||||||
"target": "EDR & AV",
|
|
||||||
"human": false,
|
|
||||||
"description": "isolate",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "SHUFFLE",
|
|
||||||
"target": "IAM",
|
|
||||||
"human": false,
|
|
||||||
"description": "Block access",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "SHUFFLE",
|
|
||||||
"target": "COMMS",
|
|
||||||
"description": "Notify oncall and affected user",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "SHUFFLE",
|
|
||||||
"target": "CASES",
|
|
||||||
"description": "Create enriched alert",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "SHUFFLE",
|
|
||||||
"target": "CASES",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "CASES",
|
|
||||||
"target": "EDR & AV",
|
|
||||||
"description": "Validate alert",
|
|
||||||
"human": true,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Exploits": {
|
"Exploits": {
|
||||||
"manual": [],
|
"manual": [],
|
||||||
"automated": [
|
"automated": [
|
||||||
@@ -220,46 +169,6 @@ export const usecases = {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"AWS S3 honeypots": {
|
|
||||||
"manual": [],
|
|
||||||
"automated": [
|
|
||||||
{
|
|
||||||
"source": "TOP_LEFT",
|
|
||||||
"target": "SIEM",
|
|
||||||
"description": "S3 logs",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"source": "SIEM",
|
|
||||||
"target": "SHUFFLE",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "SHUFFLE",
|
|
||||||
"target": "INTEL",
|
|
||||||
"description": "Add sighting",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "INTEL",
|
|
||||||
"target": "SHUFFLE",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "SHUFFLE",
|
|
||||||
"target": "CASES",
|
|
||||||
"description": "Create case",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "SHUFFLE",
|
|
||||||
"target": "NETWORK",
|
|
||||||
"description": "Block IP",
|
|
||||||
"human": false,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"SIEM alerts": {
|
"SIEM alerts": {
|
||||||
"manual": [],
|
"manual": [],
|
||||||
"automated": [
|
"automated": [
|
||||||
@@ -535,6 +444,58 @@ export const usecases = {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"Ransomware": {
|
||||||
|
"manual": [],
|
||||||
|
"automated": [
|
||||||
|
{
|
||||||
|
"source": "BOTTOM_LEFT",
|
||||||
|
"target": "EDR & AV",
|
||||||
|
"description": "EDR & AV alert",
|
||||||
|
"human": false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "EDR & AV",
|
||||||
|
"target": "SHUFFLE",
|
||||||
|
"description": "",
|
||||||
|
"human": false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "SHUFFLE",
|
||||||
|
"target": "EDR & AV",
|
||||||
|
"human": false,
|
||||||
|
"description": "isolate",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "SHUFFLE",
|
||||||
|
"target": "IAM",
|
||||||
|
"human": false,
|
||||||
|
"description": "Block access",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "SHUFFLE",
|
||||||
|
"target": "COMMS",
|
||||||
|
"description": "Notify oncall and affected user",
|
||||||
|
"human": false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "SHUFFLE",
|
||||||
|
"target": "CASES",
|
||||||
|
"description": "Create enriched alert",
|
||||||
|
"human": false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "SHUFFLE",
|
||||||
|
"target": "CASES",
|
||||||
|
"human": false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "CASES",
|
||||||
|
"target": "EDR & AV",
|
||||||
|
"description": "Validate alert",
|
||||||
|
"human": true,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
"Draw": {
|
"Draw": {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -617,7 +617,7 @@ const { globalUrl, setNotifications, notifications, isLoggedIn, removeCookie, ho
|
|||||||
<List style={{display: 'flex', flexDirection: 'row-reverse'}} component="nav">
|
<List style={{display: 'flex', flexDirection: 'row-reverse'}} component="nav">
|
||||||
<ListItem style={{textAlign: "center"}}>
|
<ListItem style={{textAlign: "center"}}>
|
||||||
<Link to="/login" style={hrefStyle}>
|
<Link to="/login" style={hrefStyle}>
|
||||||
<Button variant="outlined" color="primary" style={{textTransform: "none", borderRadius: 25, padding: "7px 14px 7px 14px", maxWidth: 100, minWidth: 100, }} onClick={() => {
|
<Button variant="outlined" style={{textTransform: "none", borderRadius: 25, padding: "7px 14px 7px 14px", maxWidth: 100, minWidth: 100, }} onClick={() => {
|
||||||
if (isCloud) {
|
if (isCloud) {
|
||||||
ReactGA.event({
|
ReactGA.event({
|
||||||
category: "header",
|
category: "header",
|
||||||
@@ -933,7 +933,8 @@ const { globalUrl, setNotifications, notifications, isLoggedIn, removeCookie, ho
|
|||||||
<div onMouseOver={handleHomeHover} onMouseOut={handleHomeHoverOut} style={{color: HomeHoverColor, cursor: "pointer"}}>
|
<div onMouseOver={handleHomeHover} onMouseOut={handleHomeHoverOut} style={{color: HomeHoverColor, cursor: "pointer"}}>
|
||||||
<Grid container direction="row" alignItems="center">
|
<Grid container direction="row" alignItems="center">
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<HomeIcon style={{marginTop: 3, marginRight: 5}} />
|
<img src={"/images/logos/orange_logo.svg"} alt="logo" style={{height: 20, width: 20, marginTop: 3, marginRight: 5, }}/>
|
||||||
|
{/*<HomeIcon style={{marginTop: 3, marginRight: 5}} />*/}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ const OrgHeader = (props) => {
|
|||||||
globalUrl,
|
globalUrl,
|
||||||
isCloud,
|
isCloud,
|
||||||
adminTab,
|
adminTab,
|
||||||
|
handleEditOrg,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@@ -83,49 +84,6 @@ const OrgHeader = (props) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEditOrg = (
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
orgId,
|
|
||||||
image,
|
|
||||||
defaults,
|
|
||||||
sso_config
|
|
||||||
) => {
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
name: name,
|
|
||||||
description: description,
|
|
||||||
org_id: orgId,
|
|
||||||
image: image,
|
|
||||||
defaults: defaults,
|
|
||||||
sso_config: sso_config,
|
|
||||||
};
|
|
||||||
|
|
||||||
const url = globalUrl + `/api/v1/orgs/${selectedOrganization.id}`;
|
|
||||||
fetch(url, {
|
|
||||||
mode: "cors",
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
credentials: "include",
|
|
||||||
crossDomain: true,
|
|
||||||
withCredentials: true,
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=utf-8",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((response) =>
|
|
||||||
response.json().then((responseJson) => {
|
|
||||||
if (responseJson["success"] === false) {
|
|
||||||
alert.error("Failed updating org: ", responseJson.reason);
|
|
||||||
} else {
|
|
||||||
alert.success("Successfully edited org!");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.catch((error) => {
|
|
||||||
alert.error("Err: " + error.toString());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var image = "";
|
var image = "";
|
||||||
const editHeaderImage = (event) => {
|
const editHeaderImage = (event) => {
|
||||||
@@ -151,10 +109,9 @@ const OrgHeader = (props) => {
|
|||||||
orgDescription,
|
orgDescription,
|
||||||
selectedOrganization.id,
|
selectedOrganization.id,
|
||||||
selectedOrganization.image,
|
selectedOrganization.image,
|
||||||
{
|
{},
|
||||||
},
|
{},
|
||||||
{
|
[],
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1636,12 +1636,12 @@ const ParsedAction = (props) => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
console.log("Clicked field: ", clickedFieldId, data.name)
|
console.log("Clicked field: ", clickedFieldId, data.name)
|
||||||
|
|
||||||
if (data.name === "file_id") {
|
//if (data.name === "file_id") {
|
||||||
console.log("show file video?")
|
// console.log("show file video?")
|
||||||
if (setShowVideo !== undefined) {
|
// if (setShowVideo !== undefined) {
|
||||||
setShowVideo("https://www.youtube.com/embed/DPYowyTbsSk")
|
// setShowVideo("https://www.youtube.com/embed/DPYowyTbsSk")
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
//(data.name.toLowerCase().includes("api") ||
|
//(data.name.toLowerCase().includes("api") ||
|
||||||
/*
|
/*
|
||||||
setExpansionModalOpen(false);
|
setExpansionModalOpen(false);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const defaultValue = {"id": "", "name": "Build your own",
|
|||||||
|
|
||||||
export const usecaseTypes = [{
|
export const usecaseTypes = [{
|
||||||
"name": "enrichment",
|
"name": "enrichment",
|
||||||
|
"aliases": ["enrichment", "enrich"],
|
||||||
"value": [{
|
"value": [{
|
||||||
"name": "EDR Ticket Enrichment",
|
"name": "EDR Ticket Enrichment",
|
||||||
"usecase_references": ["EDR to ticket"],
|
"usecase_references": ["EDR to ticket"],
|
||||||
@@ -51,6 +52,7 @@ export const usecaseTypes = [{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SIEM alert Enrichment",
|
"name": "SIEM alert Enrichment",
|
||||||
|
"aliases": ["siem alert enrichment", "siem alert enrich"],
|
||||||
"usecase_references": ["SIEM to ticket"],
|
"usecase_references": ["SIEM to ticket"],
|
||||||
"active": true,
|
"active": true,
|
||||||
"items": [{
|
"items": [{
|
||||||
@@ -66,6 +68,7 @@ export const usecaseTypes = [{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Email Enrichment",
|
"name": "Email Enrichment",
|
||||||
|
"aliases": ["email enrichment", "email enrich"],
|
||||||
"usecase_references": ["Email management"],
|
"usecase_references": ["Email management"],
|
||||||
"active": true,
|
"active": true,
|
||||||
"items": [{
|
"items": [{
|
||||||
@@ -82,6 +85,7 @@ export const usecaseTypes = [{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phishing",
|
"name": "phishing",
|
||||||
|
"aliases": ["ransomware", "phish"],
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"name": "Email analysis",
|
"name": "Email analysis",
|
||||||
@@ -100,6 +104,7 @@ export const usecaseTypes = [{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "detection",
|
"name": "detection",
|
||||||
|
"aliases": ["detection", "detect", "siem alerts", "new detections",],
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"name": "Sigma rule detection",
|
"name": "Sigma rule detection",
|
||||||
@@ -118,12 +123,13 @@ export const usecaseTypes = [{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "response",
|
"name": "response",
|
||||||
|
"aliases": ["response", "respond", "exploits"],
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"name": "EDR host isolation",
|
"name": "EDR host isolation",
|
||||||
"active": false,
|
"active": false,
|
||||||
"items": [{
|
"items": [{
|
||||||
"name": "When malicious endpoint activity is detected",
|
"name": "When exploits are detected",
|
||||||
"app_type": "edr",
|
"app_type": "edr",
|
||||||
"type": "trigger",
|
"type": "trigger",
|
||||||
},
|
},
|
||||||
@@ -133,7 +139,45 @@ export const usecaseTypes = [{
|
|||||||
"type": "subflow",
|
"type": "subflow",
|
||||||
}],
|
}],
|
||||||
}]
|
}]
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"name": "vulnerabilities",
|
||||||
|
"aliases": [],
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"name": "Vulnerability is found",
|
||||||
|
"active": false,
|
||||||
|
"items": [{
|
||||||
|
"name": "When a vulnerability is found",
|
||||||
|
"app_type": "assets",
|
||||||
|
"type": "trigger",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Patch the vulnerability",
|
||||||
|
"app_type": "edr",
|
||||||
|
"type": "subflow",
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "approvals",
|
||||||
|
"aliases": ["approval"],
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"name": "Approval is needed",
|
||||||
|
"active": false,
|
||||||
|
"items": [{
|
||||||
|
"name": "When approval is needed",
|
||||||
|
"app_type": "iam",
|
||||||
|
"type": "trigger",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Notify the user",
|
||||||
|
"app_type": "communication",
|
||||||
|
"type": "subflow",
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export const triggerlist = [
|
export const triggerlist = [
|
||||||
|
|||||||
+130
-13
@@ -163,13 +163,9 @@ const Admin = (props) => {
|
|||||||
const [selectedUser, setSelectedUser] = React.useState({});
|
const [selectedUser, setSelectedUser] = React.useState({});
|
||||||
const [newUsername, setNewUsername] = React.useState("");
|
const [newUsername, setNewUsername] = React.useState("");
|
||||||
const [newPassword, setNewPassword] = React.useState("");
|
const [newPassword, setNewPassword] = React.useState("");
|
||||||
const [selectedUserModalOpen, setSelectedUserModalOpen] =
|
const [selectedUserModalOpen, setSelectedUserModalOpen] = React.useState(false);
|
||||||
React.useState(false);
|
const [selectedAuthentication, setSelectedAuthentication] = React.useState({});
|
||||||
const [selectedAuthentication, setSelectedAuthentication] = React.useState(
|
const [selectedAuthenticationModalOpen, setSelectedAuthenticationModalOpen] = React.useState(false);
|
||||||
{}
|
|
||||||
);
|
|
||||||
const [selectedAuthenticationModalOpen, setSelectedAuthenticationModalOpen] =
|
|
||||||
React.useState(false);
|
|
||||||
const [authenticationFields, setAuthenticationFields] = React.useState([]);
|
const [authenticationFields, setAuthenticationFields] = React.useState([]);
|
||||||
const [showArchived, setShowArchived] = React.useState(false);
|
const [showArchived, setShowArchived] = React.useState(false);
|
||||||
const [isDropzone, setIsDropzone] = React.useState(false);
|
const [isDropzone, setIsDropzone] = React.useState(false);
|
||||||
@@ -179,12 +175,10 @@ const Admin = (props) => {
|
|||||||
const [secret2FA, setSecret2FA] = React.useState("");
|
const [secret2FA, setSecret2FA] = React.useState("");
|
||||||
const [show2faSetup, setShow2faSetup] = useState(false);
|
const [show2faSetup, setShow2faSetup] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
const [adminTab, setAdminTab] = React.useState(1);
|
const [adminTab, setAdminTab] = React.useState(1);
|
||||||
const [showApiKey, setShowApiKey] = useState(false);
|
const [showApiKey, setShowApiKey] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
const [billingInfo, setBillingInfo] = React.useState({});
|
const [billingInfo, setBillingInfo] = React.useState({});
|
||||||
|
const [selectedStatus, setSelectedStatus] = React.useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isDropzone) {
|
if (isDropzone) {
|
||||||
@@ -193,6 +187,8 @@ const Admin = (props) => {
|
|||||||
}
|
}
|
||||||
}, [isDropzone]);
|
}, [isDropzone]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
|
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
|
||||||
|
|
||||||
const get2faCode = (userId) => {
|
const get2faCode = (userId) => {
|
||||||
@@ -286,6 +282,20 @@ const Admin = (props) => {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const alert = useAlert();
|
const alert = useAlert();
|
||||||
|
const handleStatusChange = (event) => {
|
||||||
|
const { value } = event.target;
|
||||||
|
|
||||||
|
setSelectedStatus(value);
|
||||||
|
handleEditOrg(
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
selectedOrganization.id,
|
||||||
|
"",
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const deleteAuthentication = (data) => {
|
const deleteAuthentication = (data) => {
|
||||||
alert.info("Deleting auth " + data.label);
|
alert.info("Deleting auth " + data.label);
|
||||||
@@ -547,6 +557,54 @@ const Admin = (props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleEditOrg = (
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
orgId,
|
||||||
|
image,
|
||||||
|
defaults,
|
||||||
|
sso_config,
|
||||||
|
lead_info,
|
||||||
|
) => {
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
name: name,
|
||||||
|
description: description,
|
||||||
|
org_id: orgId,
|
||||||
|
image: image,
|
||||||
|
defaults: defaults,
|
||||||
|
sso_config: sso_config,
|
||||||
|
lead_info: lead_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
const url = globalUrl + `/api/v1/orgs/${selectedOrganization.id}`;
|
||||||
|
fetch(url, {
|
||||||
|
mode: "cors",
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
credentials: "include",
|
||||||
|
crossDomain: true,
|
||||||
|
withCredentials: true,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json; charset=utf-8",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) =>
|
||||||
|
response.json().then((responseJson) => {
|
||||||
|
if (responseJson["success"] === false) {
|
||||||
|
alert.error("Failed updating org: ", responseJson.reason);
|
||||||
|
} else {
|
||||||
|
if (lead_info === undefined || lead_info === null || lead_info === []) {
|
||||||
|
alert.success("Successfully edited org!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.catch((error) => {
|
||||||
|
alert.error("Err: " + error.toString());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const editAuthenticationConfig = (id) => {
|
const editAuthenticationConfig = (id) => {
|
||||||
const data = {
|
const data = {
|
||||||
id: id,
|
id: id,
|
||||||
@@ -696,10 +754,18 @@ const Admin = (props) => {
|
|||||||
|
|
||||||
|
|
||||||
const handleGetOrg = (orgId) => {
|
const handleGetOrg = (orgId) => {
|
||||||
|
|
||||||
|
if (serverside !== true && window.location.search !== undefined && window.location.search !== null) {
|
||||||
|
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||||
|
const params = Object.fromEntries(urlSearchParams.entries());
|
||||||
|
const foundorgid = params["org_id"];
|
||||||
|
if (foundorgid !== undefined && foundorgid !== null) {
|
||||||
|
orgId = foundorgid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (orgId.length === 0) {
|
if (orgId.length === 0) {
|
||||||
alert.error(
|
alert.error("Organization ID not defined. Please contact us on https://shuffler.io if this persists logout.");
|
||||||
"Organization ID not defined. Please contact us on https://shuffler.io if this persists logout."
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,6 +795,31 @@ const Admin = (props) => {
|
|||||||
responseJson.sync_features = {};
|
responseJson.sync_features = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (responseJson.lead_info !== undefined && responseJson.lead_info !== null) {
|
||||||
|
var leads = []
|
||||||
|
if (responseJson.lead_info.customer) {
|
||||||
|
leads.push("customer")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseJson.lead_info.demo_done) {
|
||||||
|
leads.push("demo done")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseJson.lead_info.pov) {
|
||||||
|
leads.push("pov")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseJson.lead_info.lead) {
|
||||||
|
leads.push("lead")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseJson.lead_info.student) {
|
||||||
|
leads.push("student")
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedStatus(leads)
|
||||||
|
}
|
||||||
|
|
||||||
setSelectedOrganization(responseJson)
|
setSelectedOrganization(responseJson)
|
||||||
var lists = {
|
var lists = {
|
||||||
active: {
|
active: {
|
||||||
@@ -2094,6 +2185,31 @@ const Admin = (props) => {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
*/}
|
*/}
|
||||||
|
|
||||||
|
{userdata.support === true ?
|
||||||
|
<FormControl sx={{ m: 1, width: 300, }} style={{top: -10, right: 50, position: "absolute" }}>
|
||||||
|
<InputLabel id="">Status</InputLabel>
|
||||||
|
<Select
|
||||||
|
style={{minWidth: 150, maxWidth: 150, }}
|
||||||
|
labelId="multiselect-status"
|
||||||
|
id="multiselect-status"
|
||||||
|
multiple
|
||||||
|
value={selectedStatus}
|
||||||
|
onChange={handleStatusChange}
|
||||||
|
input={<OutlinedInput label="Status" />}
|
||||||
|
renderValue={(selected) => selected.join(', ')}
|
||||||
|
MenuProps={MenuProps}
|
||||||
|
>
|
||||||
|
{["lead", "pov", "demo done", "customer", "student", ].map((name) => (
|
||||||
|
<MenuItem key={name} value={name}>
|
||||||
|
<Checkbox checked={selectedStatus.indexOf(name) > -1} />
|
||||||
|
<ListItemText primary={name} />
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
: null}
|
||||||
|
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={"Copy Organization ID"}
|
title={"Copy Organization ID"}
|
||||||
style={{}}
|
style={{}}
|
||||||
@@ -2152,6 +2268,7 @@ const Admin = (props) => {
|
|||||||
globalUrl={globalUrl}
|
globalUrl={globalUrl}
|
||||||
selectedOrganization={selectedOrganization}
|
selectedOrganization={selectedOrganization}
|
||||||
adminTab={adminTab}
|
adminTab={adminTab}
|
||||||
|
handleEditOrg={handleEditOrg}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -14787,14 +14787,6 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
<b>Status </b> {selectedResult.status}
|
<b>Status </b> {selectedResult.status}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<h1 onClick={() => {
|
|
||||||
console.log("APP: ", curapp)
|
|
||||||
console.log("Data: ", selectedResult)
|
|
||||||
}}>
|
|
||||||
HIYA: {selectedResult.action.app_name}
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
{validate.valid ? (
|
{validate.valid ? (
|
||||||
<ReactJson
|
<ReactJson
|
||||||
src={validate.result}
|
src={validate.result}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ const Search = (props) => {
|
|||||||
|
|
||||||
// Random names for type & autoComplete. Didn't research :^)
|
// Random names for type & autoComplete. Didn't research :^)
|
||||||
const landingpageDataBrowser =
|
const landingpageDataBrowser =
|
||||||
<div style={{paddingBottom: hidemargins === true ? 0 : 100, color: "white", backgroundColor: theme.palette.surfacColor}}>
|
<div style={{paddingBottom: hidemargins === true ? 0 : 100, color: "white", }}>
|
||||||
<div style={boxStyle}>
|
<div style={boxStyle}>
|
||||||
<Tabs
|
<Tabs
|
||||||
style={{width: 610, margin: "auto", marginTop: hidemargins === true ? 0 : 25, }}
|
style={{width: 610, margin: "auto", marginTop: hidemargins === true ? 0 : 25, }}
|
||||||
@@ -179,7 +179,7 @@ const Search = (props) => {
|
|||||||
|
|
||||||
// #1f2023?
|
// #1f2023?
|
||||||
return(
|
return(
|
||||||
<div style={{backgroundColor: "#1f2023",}}>
|
<div style={{}}>
|
||||||
{loadedCheck}
|
{loadedCheck}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -301,12 +301,14 @@ const Welcome = (props) => {
|
|||||||
minWidth: 300,
|
minWidth: 300,
|
||||||
backgroundColor: theme.palette.surfaceColor,
|
backgroundColor: theme.palette.surfaceColor,
|
||||||
color: "white",
|
color: "white",
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
}
|
}
|
||||||
|
|
||||||
const actionObject = {
|
const actionObject = {
|
||||||
padding: "35px",
|
padding: "35px",
|
||||||
maxHeight: 300,
|
maxHeight: 300,
|
||||||
minHeight: 300,
|
minHeight: 300,
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
}
|
}
|
||||||
|
|
||||||
const imageStyle = {
|
const imageStyle = {
|
||||||
@@ -317,10 +319,22 @@ const Welcome = (props) => {
|
|||||||
borderRadius: 75,
|
borderRadius: 75,
|
||||||
objectFit: "scale-down",
|
objectFit: "scale-down",
|
||||||
}
|
}
|
||||||
const buttonStyle = { borderRadius: 8, height: 51, width: 464, fontSize: 16, background: "linear-gradient(89.83deg, #FF8444 0.13%, #F2643B 99.84%)", padding: "16px 24px", top: 75, }
|
const buttonStyle = {
|
||||||
const experienced_image = userdata !== undefined && userdata !== null && userdata.active_org !== undefined && userdata.active_org.image !== undefined && userdata.active_org.image !== null && userdata.active_org.image !== "" ? userdata.active_org.image : "/images/experienced.png"
|
borderRadius: 8,
|
||||||
|
height: 51,
|
||||||
|
width: 464,
|
||||||
|
fontSize: 16,
|
||||||
|
background: "linear-gradient(89.83deg, #FF8444 0.13%, #F2643B 99.84%)",
|
||||||
|
padding: "16px 24px",
|
||||||
|
top: 75,
|
||||||
|
margin: "auto",
|
||||||
|
itemAlign: "center",
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultImage = "/images/experienced.png"
|
||||||
|
const experienced_image = userdata !== undefined && userdata !== null && userdata.active_org !== undefined && userdata.active_org.image !== undefined && userdata.active_org.image !== null && userdata.active_org.image !== "" ? userdata.active_org.image : defaultImage
|
||||||
return (
|
return (
|
||||||
<div style={{width: 1000, margin: "auto", backgroundColor: theme.palette.platformColor, paddingBottom: 150, minHeight: 1500, }}>
|
<div style={{width: 1000, margin: "auto", paddingBottom: 150, minHeight: 1500, }}>
|
||||||
{/*
|
{/*
|
||||||
<div style={{position: "fixed", bottom: 110, right: 110, display: "flex", }}>
|
<div style={{position: "fixed", bottom: 110, right: 110, display: "flex", }}>
|
||||||
<img src="/images/Arrow.png" style={{width: 250, height: "100%",}} />
|
<img src="/images/Arrow.png" style={{width: 250, height: "100%",}} />
|
||||||
@@ -439,14 +453,14 @@ const Welcome = (props) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
*/}
|
*/}
|
||||||
<Typography variant="h4" style={{color: "#F1F1F1", textAlign: "center", paddingRight: "300px"}}>
|
<Typography variant="h4" style={{color: "#F1F1F1", textAlign: "center", marginTop: 50, }}>
|
||||||
Help us get to know you.
|
Help us get to know you
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" style={{color: "#9E9E9E", textAlign: "center", marginBottom: 50, paddingRight: "366px"}}>
|
<Typography variant="body1" style={{color: "#9E9E9E", textAlign: "center", marginBottom: 50,}}>
|
||||||
Let us help you create a smoother journey.
|
We will use this information to personalize your automation
|
||||||
</Typography>
|
</Typography>
|
||||||
<div style={{display: "flex", marginTop: 70, width: 700, margin: "auto",}}>
|
<div style={{display: "flex", marginTop: 70, width: 700, margin: "auto",}}>
|
||||||
<div style={{border: "1px solid #806BFF",}}>
|
<div style={{border: "1px solid #806BFF", borderRadius: theme.palette.borderRadius, }}>
|
||||||
<Card style={paperObject} onClick={() => {
|
<Card style={paperObject} onClick={() => {
|
||||||
if (isCloud) {
|
if (isCloud) {
|
||||||
ReactGA.event({
|
ReactGA.event({
|
||||||
@@ -466,7 +480,7 @@ const Welcome = (props) => {
|
|||||||
New to Shuffle
|
New to Shuffle
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" style={{marginTop: 10, color: "rgba(255,255,255,0.8)"}}>
|
<Typography variant="body1" style={{marginTop: 10, color: "rgba(255,255,255,0.8)"}}>
|
||||||
Let us guide you for an easier experience.
|
Let us guide you for an easier experience
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardActionArea>
|
</CardActionArea>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -488,37 +502,38 @@ const Welcome = (props) => {
|
|||||||
navigate("/workflows?message=Skipped intro")
|
navigate("/workflows?message=Skipped intro")
|
||||||
}}>
|
}}>
|
||||||
<CardActionArea style={actionObject}>
|
<CardActionArea style={actionObject}>
|
||||||
<img src={experienced_image} style={{padding: "38px", objectFit: "scale-down", minHeight: 40, maxHeight: 40, }} />
|
<img src={experienced_image} style={{padding: experienced_image === defaultImage ? 38 : 10, objectFit: "scale-down", minHeight: experienced_image === defaultImage ? 40 : 70, maxHeight: experienced_image === defaultImage ? 40 : 70, bordeRadius: theme.palette.borderRadius, }} />
|
||||||
<Typography variant="h4" style={{color: "#F1F1F1"}}>
|
<Typography variant="h4" style={{color: "#F1F1F1"}}>
|
||||||
Experienced
|
Experienced
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body1" style={{marginTop: 10, color: "rgba(255,255,255,0.8)"}}>
|
<Typography variant="body1" style={{marginTop: 10, color: "rgba(255,255,255,0.8)"}}>
|
||||||
You will head to Shuffle right away.
|
Head to Shuffle right away
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardActionArea>
|
</CardActionArea>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/*
|
||||||
<div style={{display: "flex", flexDirection: "row", }}>
|
<div style={{display: "flex", flexDirection: "row", }}>
|
||||||
<Button variant="contained" type="submit" fullWidth style={buttonStyle} onClick={() => {
|
<Button variant="contained" type="submit" fullWidth style={buttonStyle} onClick={() => {
|
||||||
navigate("/workflows?message=Skipped intro")
|
navigate("/workflows?message=Skipped intro continue")
|
||||||
}}>
|
}}>
|
||||||
Continue
|
Continue
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{/*
|
*/}
|
||||||
<div style={{margin: "auto", border: "1px solid rgba(255,255,255,0.5)", borderRadius: theme.palette.borderRadius, marginTop: 50, width: 200, overflow: "wrap", padding: 25, cursor: "pointer", }} onClick={() => {
|
|
||||||
|
<div style={{margin: "auto", borderRadius: theme.palette.borderRadius, marginTop: 50, width: 200, overflow: "wrap", padding: 25, cursor: "pointer", }} onClick={() => {
|
||||||
if (window.drift !== undefined) {
|
if (window.drift !== undefined) {
|
||||||
window.drift.api.startInteraction({ interactionId: 341911 })
|
window.drift.api.startInteraction({ interactionId: 340045 })
|
||||||
} else {
|
} else {
|
||||||
console.log("Couldn't find drift in window.drift and not .drift-open-chat with querySelector: ", window.drift)
|
console.log("Couldn't find drift in window.drift and not .drift-open-chat with querySelector: ", window.drift)
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
<Typography variant="body1" style={{margin: "auto", textAlign: "center"}}>
|
<Typography variant="body1" style={{margin: "auto", textAlign: "center"}}>
|
||||||
Want a free Proof of Value with our support team?
|
Want a demo instead?
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
*/}
|
|
||||||
</div>
|
</div>
|
||||||
</Fade>
|
</Fade>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3447,6 +3447,26 @@ const Workflows = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
{/*userdata.priorities !== undefined && userdata.priorities !== null && userdata.priorities.length > 0 ?
|
||||||
|
<div style={{width: "100%", border: "1px solid rgba(255,255,255,0.1)", borderRadius: theme.palette.borderRadius, marginTop: 10, marginBottom: 10, padding: 15, textAlign: "center", height: 70, textAlign: "left", backgroundColor: theme.palette.surfaceColor, display: "flex", }}>
|
||||||
|
<div style={{flex: 2, overflow: "hidden",}}>
|
||||||
|
<Typography variant="body1" >
|
||||||
|
{userdata.priorities[0].name}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="textSecondary">
|
||||||
|
{userdata.priorities[0].description}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<div style={{flex: 1, display: "flex", marginLeft: 30, }}>
|
||||||
|
<Button style={{height: 50, borderRadius: 25, marginTop: 8, width: 200, }} variant="contained" color="secondary" onClick={() => {navigate(userdata.priorities[0].url)}}>
|
||||||
|
Continue
|
||||||
|
</Button>
|
||||||
|
<Button style={{borderRadius: 25, width: 200, height: 50, marginTop: 8, }} variant="text" color="secondary">
|
||||||
|
Ignore
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
: null*/}
|
||||||
|
|
||||||
<div style={{marginTop: 15, }}>
|
<div style={{marginTop: 15, }}>
|
||||||
{view === "grid" ? (
|
{view === "grid" ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user