feat: Introduce generic auth steps
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
"name": "@automatisch/root",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "lerna run --stream --scope @*/{web,backend} dev",
|
||||
"start:web": "lerna run --stream --scope @*/web start",
|
||||
"start:backend": "lerna run --stream --scope @*/backend dev"
|
||||
},
|
||||
|
@@ -55,7 +55,7 @@
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"value": "data",
|
||||
"value": null,
|
||||
"fields": [
|
||||
{
|
||||
"name": "consumerKey",
|
||||
@@ -76,7 +76,7 @@
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"value": "{response.credentialId}"
|
||||
"value": "{createCredential.id}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -1,15 +1,15 @@
|
||||
import { GraphQLNonNull, GraphQLInt } from 'graphql';
|
||||
import { GraphQLNonNull, GraphQLString } from 'graphql';
|
||||
import Credential from '../../models/credential';
|
||||
import authLinkType from '../types/auth-link';
|
||||
import RequestWithCurrentUser from '../../types/express/request-with-current-user';
|
||||
|
||||
type Params = {
|
||||
credentialId: number,
|
||||
id: number,
|
||||
}
|
||||
const createAuthLinkResolver = async (params: Params, req: RequestWithCurrentUser) => {
|
||||
const credential = await Credential.query().findOne({
|
||||
user_id: req.currentUser.id,
|
||||
id: params.credentialId
|
||||
id: params.id
|
||||
})
|
||||
|
||||
const appClass = (await import(`../../apps/${credential.key}`)).default;
|
||||
@@ -23,7 +23,7 @@ const createAuthLinkResolver = async (params: Params, req: RequestWithCurrentUse
|
||||
const createAuthLink = {
|
||||
type: authLinkType,
|
||||
args: {
|
||||
credentialId: { type: GraphQLNonNull(GraphQLInt) },
|
||||
id: { type: GraphQLNonNull(GraphQLString) },
|
||||
},
|
||||
resolve: (_: any, params: Params, req: RequestWithCurrentUser) => createAuthLinkResolver(params, req)
|
||||
};
|
||||
|
@@ -12,12 +12,14 @@
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
"@types/jest": "^26.0.15",
|
||||
"@types/lodash.template": "^4.5.0",
|
||||
"@types/node": "^12.0.0",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"@types/react-router-dom": "^5.3.0",
|
||||
"clipboard-copy": "^4.0.1",
|
||||
"graphql": "^15.6.0",
|
||||
"lodash.template": "^4.5.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-hook-form": "^7.17.2",
|
||||
@@ -28,7 +30,7 @@
|
||||
"web-vitals": "^1.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"dev": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { useApolloClient, useMutation } from '@apollo/client';
|
||||
import DialogTitle from '@mui/material/DialogTitle';
|
||||
import DialogContent from '@mui/material/DialogContent';
|
||||
import DialogContentText from '@mui/material/DialogContentText';
|
||||
@@ -6,8 +6,9 @@ import Dialog from '@mui/material/Dialog';
|
||||
import Button from '@mui/material/Button';
|
||||
import { FieldValues, SubmitHandler } from 'react-hook-form';
|
||||
|
||||
import computeAuthStepVariables from 'helpers/computeAuthStepVariables';
|
||||
import InputCreator from 'components/InputCreator';
|
||||
import { CREATE_CREDENTIALS } from 'graphql/mutations/create-credentials';
|
||||
import MUTATIONS from 'graphql/mutations';
|
||||
import type { App } from 'types/app';
|
||||
import { Form } from './style';
|
||||
|
||||
@@ -16,26 +17,33 @@ type AddAppConnectionProps = {
|
||||
application: App;
|
||||
};
|
||||
|
||||
type Response = {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export default function AddAppConnection(props: AddAppConnectionProps){
|
||||
const { application, onClose } = props;
|
||||
const { name, fields } = application;
|
||||
const { key, fields, authenticationSteps } = application;
|
||||
|
||||
const [createCredentials, { data: newCredentials }] = useMutation(CREATE_CREDENTIALS);
|
||||
console.log('newCredentials', newCredentials)
|
||||
const apollo = useApolloClient();
|
||||
|
||||
const submitHandler: SubmitHandler<FieldValues> = (data) => {
|
||||
const variables = {
|
||||
key: application.key,
|
||||
displayName: data.displayName,
|
||||
data: {
|
||||
consumerKey: data.consumerKey,
|
||||
consumerSecret: data.consumerSecret
|
||||
}
|
||||
const submitHandler: SubmitHandler<FieldValues> = async (data) => {
|
||||
const response: Response = {
|
||||
key,
|
||||
fields: data,
|
||||
};
|
||||
|
||||
createCredentials({ variables });
|
||||
for await (const authenticationStep of authenticationSteps) {
|
||||
const mutation = MUTATIONS[authenticationStep.name as string];
|
||||
const variables = computeAuthStepVariables(authenticationStep, response);
|
||||
|
||||
onClose?.();
|
||||
const mutationResponse: any = await apollo.mutate({
|
||||
mutation,
|
||||
variables,
|
||||
});
|
||||
|
||||
response[authenticationStep.name] = mutationResponse.data[authenticationStep.name];
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
9
packages/web/src/graphql/mutations/create-auth-link.ts
Normal file
9
packages/web/src/graphql/mutations/create-auth-link.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const CREATE_AUTH_LINK = gql`
|
||||
mutation CreateAuthLink($id: String!) {
|
||||
createAuthLink(id: $id) {
|
||||
url
|
||||
}
|
||||
}
|
||||
`;
|
@@ -1,10 +1,10 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const CREATE_CREDENTIALS = gql`
|
||||
mutation CreateCredentials($displayName: String!, $key: String!, $data: twitterCredentialInput!) {
|
||||
createCredential(displayName: $displayName, key: $key, data: $data) {
|
||||
export const CREATE_CREDENTIAL = gql`
|
||||
mutation CreateCredential($key: String!, $data: twitterCredentialInput!) {
|
||||
createCredential(key: $key, data: $data) {
|
||||
key
|
||||
displayName
|
||||
id
|
||||
data {
|
||||
consumerKey
|
||||
consumerSecret
|
||||
|
13
packages/web/src/graphql/mutations/index.ts
Normal file
13
packages/web/src/graphql/mutations/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { CREATE_CREDENTIAL } from './create-credentials';
|
||||
import { CREATE_AUTH_LINK } from './create-auth-link';
|
||||
|
||||
type Mutations = {
|
||||
[key: string]: any,
|
||||
}
|
||||
|
||||
const mutations: Mutations = {
|
||||
createCredential: CREATE_CREDENTIAL,
|
||||
createAuthLink: CREATE_AUTH_LINK,
|
||||
};
|
||||
|
||||
export default mutations;
|
@@ -19,6 +19,19 @@ export const GET_APP = gql`
|
||||
docUrl
|
||||
clickToCopy
|
||||
}
|
||||
authenticationSteps {
|
||||
step
|
||||
type
|
||||
name
|
||||
fields {
|
||||
name
|
||||
value
|
||||
fields {
|
||||
name
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
25
packages/web/src/helpers/computeAuthStepVariables.ts
Normal file
25
packages/web/src/helpers/computeAuthStepVariables.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import template from 'lodash.template';
|
||||
|
||||
const interpolate = /{([\s\S]+?)}/g;
|
||||
|
||||
type VARIABLES = {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
const computeAuthStepVariables = (authStep: any, aggregatedData: any) => {
|
||||
const variables: VARIABLES = {};
|
||||
|
||||
for (const field of authStep.fields) {
|
||||
if (field.fields) {
|
||||
variables[field.name] = computeAuthStepVariables(field, aggregatedData);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
variables[field.name] = template(field.value, { interpolate })(aggregatedData);
|
||||
}
|
||||
|
||||
return variables;
|
||||
};
|
||||
|
||||
export default computeAuthStepVariables;
|
@@ -17,6 +17,7 @@ type App = {
|
||||
docUrl: string;
|
||||
primaryColor: string;
|
||||
fields: AppFields[];
|
||||
authenticationSteps: any[];
|
||||
};
|
||||
|
||||
export type { App, AppFields };
|
||||
|
Reference in New Issue
Block a user