refactor: Introduce generator for auth steps

This commit is contained in:
Ali BARIN
2021-10-15 00:31:30 +02:00
parent e045fb1710
commit bfd63204a2

View File

@@ -1,4 +1,4 @@
import { useEffect } from 'react'; import { useCallback, useEffect } from 'react';
import { useApolloClient } from '@apollo/client'; import { useApolloClient } from '@apollo/client';
import DialogTitle from '@mui/material/DialogTitle'; import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent'; import DialogContent from '@mui/material/DialogContent';
@@ -25,14 +25,28 @@ type Response = {
const BASE_URL = 'http://localhost:3001'; const BASE_URL = 'http://localhost:3001';
const parseData = (event: any) => { const parseData = (event: any) => {
// Do we trust the sender of this message? (might be const searchParams = new URLSearchParams(event.data);
// different from what we originally opened, for example).
if (event.origin !== BASE_URL) { return getObjectOfEntries(searchParams.entries());
return; };
function getObjectOfEntries(iterator: any) {
const result: any = {};
for (const [key, value] of iterator) {
result[key] = value;
} }
return new URLSearchParams(event.data); return result;
}; }
function* authStepGenerator(steps: any[]) {
for (const step of steps) {
yield step;
}
return;
}
export default function AddAppConnection(props: AddAppConnectionProps){ export default function AddAppConnection(props: AddAppConnectionProps){
const { application, onClose } = props; const { application, onClose } = props;
@@ -42,43 +56,69 @@ export default function AddAppConnection(props: AddAppConnectionProps){
useEffect(() => { useEffect(() => {
if (window.opener) { if (window.opener) {
window.opener.postMessage(window.location.search); window.opener.postMessage({ source: 'automatisch', payload: window.location.search });
window.close(); window.close();
} }
}); }, []);
const submitHandler: SubmitHandler<FieldValues> = async (data) => { const submitHandler: SubmitHandler<FieldValues> = useCallback(async (data) => {
const response: Response = { const response: Response = {
key, key,
fields: data, fields: data,
}; };
for await (const authenticationStep of authenticationSteps) { const stepGenerator = authStepGenerator(authenticationSteps);
const variables = computeAuthStepVariables(authenticationStep, response);
if (authenticationStep.type === 'mutation') { const processStep = async (step: any) => {
const mutation = MUTATIONS[authenticationStep.name as string]; const variables = computeAuthStepVariables(step, response);
const mutationResponse: any = await apollo.mutate({ if (step.type === 'mutation') {
mutation, const mutation = MUTATIONS[step.name];
variables, const mutationResponse = await apollo.mutate({ mutation, variables });
}); const responseData = mutationResponse.data[step.name];
const responseData = mutationResponse.data[authenticationStep.name]; response[step.name] = responseData;
response[authenticationStep.name] = responseData;
}
if (authenticationStep.type === 'openWithPopup') { const nextStep = stepGenerator.next();
if (!nextStep.done) {
await processStep(nextStep.value);
}
} else if (step.type === 'openWithPopup') {
const windowFeatures = 'toolbar=no, menubar=no, width=600, height=700, top=100, left=100'; const windowFeatures = 'toolbar=no, menubar=no, width=600, height=700, top=100, left=100';
const url = variables.url; const url = variables.url;
const popup: any = window.open(url, '_blank', windowFeatures); const popup: any = window.open(url, '_blank', windowFeatures);
popup?.focus(); popup?.focus();
window.addEventListener('message', parseData, false); const messageHandler = async (event: any) => {
// check origin and data.source to trust the event
if (event.origin !== BASE_URL || event.data.source !== 'automatisch') {
return;
}
const data = parseData(event);
response[step.name] = data;
const nextStep = stepGenerator.next();
if (!nextStep.done) {
await processStep(nextStep.value);
}
window.removeEventListener('message', messageHandler);
};
window.addEventListener('message', messageHandler, false);
} }
} }
};
const firstStep = stepGenerator.next();
if (!firstStep.done) {
await processStep(firstStep.value);
}
}, [apollo, authenticationSteps, key]);
return ( return (
<Dialog open={true} onClose={onClose}> <Dialog open={true} onClose={onClose}>