GraphQL: 3rd Party LoginWith Support (#6371)

* wip

* wip

* tested
This commit is contained in:
Antoine Cormouls
2020-01-28 03:57:26 +01:00
committed by Antonio Davi Macedo Coelho de Castro
parent b22ccec2ce
commit d4e264daf8
2 changed files with 154 additions and 6 deletions

View File

@@ -4,6 +4,7 @@ const req = require('../lib/request');
const fetch = require('node-fetch');
const FormData = require('form-data');
const ws = require('ws');
require('./helper');
const pluralize = require('pluralize');
const { getMainDefinition } = require('apollo-utilities');
const { ApolloLink, split } = require('apollo-link');
@@ -907,7 +908,7 @@ describe('ParseGraphQLServer', () => {
.map(field => field.name)
.sort();
expect(inputFields).toEqual(['clientMutationId', 'userFields']);
expect(inputFields).toEqual(['clientMutationId', 'fields']);
});
it('should have clientMutationId in sign up mutation payload', async () => {
@@ -7114,7 +7115,7 @@ describe('ParseGraphQLServer', () => {
variables: {
input: {
clientMutationId,
userFields: {
fields: {
username: 'user1',
password: 'user1',
someField: 'someValue',
@@ -7129,6 +7130,63 @@ describe('ParseGraphQLServer', () => {
expect(typeof result.data.signUp.viewer.sessionToken).toBe('string');
});
it('should login with user', async () => {
const clientMutationId = uuidv4();
const userSchema = new Parse.Schema('_User');
parseServer = await global.reconfigureServer({
publicServerURL: 'http://localhost:13377/parse',
auth: {
myAuth: {
module: global.mockCustomAuthenticator('parse', 'graphql'),
},
},
});
userSchema.addString('someField');
await userSchema.update();
await parseGraphQLServer.parseGraphQLSchema.databaseController.schemaCache.clear();
const result = await apolloClient.mutate({
mutation: gql`
mutation LogInWith($input: LogInWithInput!) {
logInWith(input: $input) {
clientMutationId
viewer {
sessionToken
user {
someField
}
}
}
}
`,
variables: {
input: {
clientMutationId,
authData: {
myAuth: {
id: 'parse',
password: 'graphql',
},
},
fields: {
someField: 'someValue',
},
},
},
});
expect(result.data.logInWith.clientMutationId).toEqual(
clientMutationId
);
expect(result.data.logInWith.viewer.sessionToken).toBeDefined();
expect(result.data.logInWith.viewer.user.someField).toEqual(
'someValue'
);
expect(typeof result.data.logInWith.viewer.sessionToken).toBe(
'string'
);
});
it('should log the user in', async () => {
const clientMutationId = uuidv4();
const user = new Parse.User();

View File

@@ -1,7 +1,13 @@
import { GraphQLNonNull, GraphQLString, GraphQLBoolean } from 'graphql';
import {
GraphQLNonNull,
GraphQLString,
GraphQLBoolean,
GraphQLInputObjectType,
} from 'graphql';
import { mutationWithClientMutationId } from 'graphql-relay';
import UsersRouter from '../../Routers/UsersRouter';
import * as objectsMutations from '../helpers/objectsMutations';
import { OBJECT } from './defaultGraphQLTypes';
import { getUserFromSessionToken } from './usersQueries';
const usersRouter = new UsersRouter();
@@ -16,7 +22,7 @@ const load = parseGraphQLSchema => {
description:
'The signUp mutation can be used to create and sign up a new user.',
inputFields: {
userFields: {
fields: {
descriptions:
'These are the fields of the new user to be created and signed up.',
type:
@@ -32,12 +38,12 @@ const load = parseGraphQLSchema => {
},
mutateAndGetPayload: async (args, context, mutationInfo) => {
try {
const { userFields } = args;
const { fields } = args;
const { config, auth, info } = context;
const { sessionToken } = await objectsMutations.createObject(
'_User',
userFields,
fields,
config,
auth,
info
@@ -67,6 +73,90 @@ const load = parseGraphQLSchema => {
);
parseGraphQLSchema.addGraphQLType(signUpMutation.type, true, true);
parseGraphQLSchema.addGraphQLMutation('signUp', signUpMutation, true, true);
const logInWithMutation = mutationWithClientMutationId({
name: 'LogInWith',
description:
'The logInWith mutation can be used to signup, login user with 3rd party authentication system. This mutation create a user if the authData do not correspond to an existing one.',
inputFields: {
authData: {
descriptions: 'This is the auth data of your custom auth provider',
type: new GraphQLNonNull(OBJECT),
},
fields: {
descriptions:
'These are the fields of the user to be created/updated and logged in.',
type: new GraphQLInputObjectType({
name: 'UserLoginWithInput',
fields: () => {
const classGraphQLCreateFields = parseGraphQLSchema.parseClassTypes[
'_User'
].classGraphQLCreateType.getFields();
return Object.keys(classGraphQLCreateFields).reduce(
(fields, fieldName) => {
if (
fieldName !== 'password' &&
fieldName !== 'username' &&
fieldName !== 'authData'
) {
fields[fieldName] = classGraphQLCreateFields[fieldName];
}
return fields;
},
{}
);
},
}),
},
},
outputFields: {
viewer: {
description:
'This is the new user that was created, signed up and returned as a viewer.',
type: new GraphQLNonNull(parseGraphQLSchema.viewerType),
},
},
mutateAndGetPayload: async (args, context, mutationInfo) => {
try {
const { fields, authData } = args;
const { config, auth, info } = context;
const { sessionToken } = await objectsMutations.createObject(
'_User',
{ ...fields, authData },
config,
auth,
info
);
info.sessionToken = sessionToken;
return {
viewer: await getUserFromSessionToken(
config,
info,
mutationInfo,
'viewer.user.',
true
),
};
} catch (e) {
parseGraphQLSchema.handleError(e);
}
},
});
parseGraphQLSchema.addGraphQLType(
logInWithMutation.args.input.type.ofType,
true,
true
);
parseGraphQLSchema.addGraphQLType(logInWithMutation.type, true, true);
parseGraphQLSchema.addGraphQLMutation(
'logInWith',
logInWithMutation,
true,
true
);
const logInMutation = mutationWithClientMutationId({
name: 'LogIn',