import React, { useState, useEffect, useContext, memo } from "react";
import { CodeHandler, Img, OuterLink, } from '../views/Docs.jsx'
import { getTheme } from "../theme.jsx";
import { isMobile } from "react-device-detect"
import Markdown from "react-markdown";
import { Context } from '../context/ContextApi.jsx';
import PaperComponent from "../components/PaperComponent.jsx";
import { toast } from "react-toastify";
import { v4 as uuidv4} from "uuid";
import AuthenticationOauth2 from "../components/Oauth2Auth.jsx";
import {
Edit as EditIcon,
DragIndicator as DragIndicatorIcon,
Close as CloseIcon,
LockOpen as LockOpenIcon,
} from "@mui/icons-material";
import {
Button,
Typography,
Dialog,
DialogContent,
DialogTitle,
DialogActions,
MenuItem,
Select,
TextField,
IconButton,
Tooltip,
Divider,
} from "@mui/material";
const AuthenticationModal = (props) => {
const {
globalUrl,
userdata,
selectedAppData,
getAppAuthentication,
appAuthentication,
setSelectedAction,
selectedMeta,
setSelectedMeta,
setAppAuthentication,
} = props;
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" || window.location.host === "migration.shuffler.io";
const [selectedAuthentication, setSelectedAuthentication] = React.useState({});
const [authenticationModalOpen, setAuthenticationModalOpen] = React.useState(false);
const [authenticationType, setAuthenticationType] = React.useState({})
const [appid, setAppId] = useState("")
//const [appAuthentication, setAppAuthentication] = useState([]);
const { themeMode, supportEmail, brandColor } = useContext(Context)
const theme = getTheme(themeMode, brandColor)
useEffect(() => {
if (selectedAppData === undefined || selectedAppData === null || Object.getOwnPropertyNames(selectedAppData).length === 0) {
return
}
if (selectedAppData.authentication === undefined || selectedAppData.authentication === null) {
setAuthenticationType({
type: "",
})
selectedAppData.authentication = {
type: "",
required: false,
}
} else {
setAuthenticationType(
selectedAppData.authentication.type === "oauth2-app" || (selectedAppData.authentication.type === "oauth2" && selectedAppData.authentication.redirect_uri !== undefined && selectedAppData.authentication.redirect_uri !== null) ? {
type: selectedAppData.authentication.type,
redirect_uri: selectedAppData.authentication.redirect_uri,
refresh_uri: selectedAppData.authentication.refresh_uri,
token_uri: selectedAppData.authentication.token_uri,
scope: selectedAppData.authentication.scope,
client_id: selectedAppData.authentication.client_id,
client_secret: selectedAppData.authentication.client_secret,
grant_type: selectedAppData.authentication.grant_type,
} : {
type: "",
}
)
}
}, [selectedAppData])
if (selectedAppData === undefined || selectedAppData === null || Object.getOwnPropertyNames(selectedAppData).length === 0) {
console.log("No app data for authentication modal");
return null
}
if (authenticationModalOpen === false) {
return (
{
setAppId(selectedAppData?.id)
setAuthenticationModalOpen(true)
}}
color="primary"
>
Authenticate {selectedAppData?.name?.replaceAll("_", " ", -1)}
)
}
function Heading(props) {
const element = React.createElement(
`h${props.level}`,
{ style: { marginTop: 40 } },
props.children
);
return (
{props.level !== 1 ? (
) : null}
{element}
);
}
const UpdateAppAuthentication = (data) => {
if (data === undefined || data === null) {
return;
}
const filteredData = data.filter((appAuth) => appAuth?.app?.id === appid);
if (filteredData.length === 0) {
setAppAuthentication([]);
setSelectedAuthentication({});
} else {
setAppAuthentication(filteredData);
setSelectedAuthentication(filteredData[0]);
}
};
const HandleAppAuthentication = () => {
const url = `${globalUrl}/api/v1/apps/authentication`;
fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
}).then((response) => {
if (response.status !== 200) {
return;
}
return response.json();
}).then((responseJson) => {
if (responseJson.success === true) {
UpdateAppAuthentication(responseJson.data);
} else {
toast.error("Failed to get app authentication data");
}
}).catch((error) => {
console.error("error for app is :", error);
});
}
const AuthenticationData = (props) => {
const selectedApp = props.app;
const [authenticationOption, setAuthenticationOptions] = React.useState({
app: JSON.parse(JSON.stringify(selectedApp)),
fields: {},
label: "",
usage: [
{
// workflow_id: workflow.id,
},
],
id: uuidv4(),
active: true,
});
if (
selectedApp.authentication === undefined ||
selectedApp.authentication.parameters === null ||
selectedApp.authentication.parameters === undefined ||
selectedApp.authentication.parameters.length === 0
) {
return (
{selectedApp.name} does not require authentication
);
}
authenticationOption.app.actions = [];
for (let paramkey in selectedApp.authentication.parameters) {
if (
authenticationOption.fields[
selectedApp.authentication.parameters[paramkey].name
] === undefined
) {
authenticationOption.fields[
selectedApp.authentication.parameters[paramkey].name
] = "";
}
}
const setNewAppAuth = (appAuthData, refresh) => {
setSelectedAuthentication(appAuthData);
var headers = {
"Content-Type": "application/json",
"Accept": "application/json",
}
headers["Org-Id"] = userdata?.active_org?.id
fetch(globalUrl + "/api/v1/apps/authentication", {
method: "PUT",
headers: headers,
body: JSON.stringify(appAuthData),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for setting app auth :O!");
if (response.status === 400) {
toast.error("Failed setting new auth. Please try again", {
"autoClose": true,
})
}
}
return response.json();
})
.then((responseJson) => {
if (!responseJson.success) {
toast.error("Error: " + responseJson.reason, {
"autoClose": false,
})
} else {
HandleAppAuthentication()
setAuthenticationModalOpen(false)
getAppAuthentication()
}
})
.catch((error) => {
console.log("New auth error: ", error.toString());
});
};
const handleSubmitCheck = () => {
if (authenticationOption.label.length === 0) {
authenticationOption.label = `Auth for ${selectedApp.name}`;
}
for (let paramkey in selectedApp.authentication.parameters) {
if (
authenticationOption.fields[
selectedApp.authentication.parameters[paramkey].name
].length === 0
) {
if (
selectedApp.authentication.parameters[paramkey].value !== undefined &&
selectedApp.authentication.parameters[paramkey].value !== null &&
selectedApp.authentication.parameters[paramkey].value.length > 0
) {
authenticationOption.fields[
selectedApp.authentication.parameters[paramkey].name
] = selectedApp.authentication.parameters[paramkey].value;
} else {
if (
selectedApp.authentication.parameters[paramkey].schema.type === "bool"
) {
authenticationOption.fields[
selectedApp.authentication.parameters[paramkey].name
] = "false";
} else {
toast(
"Field " +
selectedApp.authentication.parameters[paramkey].name +
" can't be empty"
);
return;
}
}
}
}
var newAuthOption = JSON.parse(JSON.stringify(authenticationOption));
var newFields = [];
for (let authkey in newAuthOption.fields) {
const value = newAuthOption.fields[authkey];
newFields.push({
"key": authkey,
"value": value,
});
}
newAuthOption.fields = newFields
setNewAppAuth(newAuthOption)
}
if (authenticationOption.label === null || authenticationOption.label === undefined) {
authenticationOption.label = selectedApp.name + " authentication";
}
return (
Authentication for {selectedApp.name.replaceAll("_", " ", -1)}
What is app authentication?
These are required fields for authenticating with {selectedApp.name}
Label for you to remember
{
authenticationOption.label = event.target.value;
}}
/>
{selectedApp.authentication.parameters.map((data, index) => {
if (data.value === "" || data.value === null || data.value === undefined || data.name === "url") {
}
return (
{data.name}
{data.schema !== undefined &&
data.schema !== null &&
data.schema.type === "bool" ? (
{
authenticationOption.fields[data.name] = e.target.value;
}}
style={{
backgroundColor: theme.palette.surfaceColor,
color: theme.palette.textColor,
height: 50,
}}
>
false
true
) : (
{
authenticationOption.fields[data.name] =
event.target.value;
}}
/>
)}
);
})}
{
setAuthenticationModalOpen(false);
}}
color="secondary"
>
Cancel
{
setAuthenticationOptions(authenticationOption);
handleSubmitCheck()
}}
color="primary"
>
Submit
);
};
const authenticationModal = authenticationModalOpen ? (
{setSelectedMeta(undefined)}}
PaperProps={{
style: {
pointerEvents: "auto",
color: theme.palette.textColor,
minWidth: 1100,
minHeight: 800,
maxHeight: 800,
padding: 15,
overflow: "hidden",
zIndex: 10012,
border: theme.palette.defaultBorder,
},
}}
>
{ selectedAppData.reference_info === undefined ||
selectedAppData.reference_info === null ||
selectedAppData.reference_info.github_url === undefined ||
selectedAppData.reference_info.github_url === null ||
selectedAppData.reference_info.github_url.length === 0 ? (
) : (
)}
{
setAuthenticationModalOpen(false);
}}
>
{authenticationType?.type === "oauth2" || authenticationType?.type === "oauth2-app" ?
:
}
{selectedAppData?.documentation === undefined ||
selectedAppData?.documentation === null ||
selectedAppData?.documentation.length === 0 ? (
{selectedAppData?.description}
There is no Shuffle-specific documentation for this app yet outside of the general description above. Documentation is written for each api, and is a community effort. We hope to see your contribution!
{
toast.success("Opening remote Github documentation link. Thanks for contributing!")
setTimeout(() => {
window.open(`https://github.com/Shuffle/openapi-apps/new/master/docs?filename=${selectedAppData.name.toLowerCase()}.md`, "_blank")
}, 2500)
}}
>
Create Docs
Want to help the making of, or improve this app?{" "}
Join the community on Discord!
Want to help change this app directly?
{selectedAppData.reference_info === undefined ||
selectedAppData.reference_info === null ||
selectedAppData.reference_info.github_url === undefined ||
selectedAppData.reference_info.github_url === null ||
selectedAppData.reference_info.github_url.length === 0 ? (
Check it out on Github!
) : (
Check it out on Github!
)}
) : (
{selectedMeta !== undefined && selectedMeta !== null && Object.getOwnPropertyNames(selectedMeta).length > 0 && selectedMeta.name !== undefined && selectedMeta.name !== null ?
{isMobile ? null : (
Edit
)}
{isMobile ? null : (
)}
{selectedMeta.read_time} minute
{selectedMeta.read_time === 1 ? "" : "s"} to read
{isMobile ||
selectedMeta.contributors === undefined ||
selectedMeta.contributors === null ? (
""
) : (
{selectedMeta.contributors.slice(0, 7).map((data, index) => {
return (
);
})}
)}
: null}
{selectedAppData.documentation}
)}
) : null;
return authenticationModal
}
export default AuthenticationModal;