From 0115951b68ba94d596cc1a47747f59363d809992 Mon Sep 17 00:00:00 2001 From: Antoine Cormouls Date: Mon, 27 Jan 2020 12:06:19 +0100 Subject: [PATCH 1/3] wip --- src/GraphQL/loaders/usersMutations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GraphQL/loaders/usersMutations.js b/src/GraphQL/loaders/usersMutations.js index a25db157e1..3c95bcda1c 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -16,7 +16,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: From 3a18acc42d59c464c364f67a42f0614d4e00b26b Mon Sep 17 00:00:00 2001 From: Antoine Cormouls Date: Mon, 27 Jan 2020 15:26:42 +0100 Subject: [PATCH 2/3] wip --- src/GraphQL/loaders/usersMutations.js | 104 +++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/src/GraphQL/loaders/usersMutations.js b/src/GraphQL/loaders/usersMutations.js index 3c95bcda1c..fd5fd92dae 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -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(); @@ -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,98 @@ const load = parseGraphQLSchema => { ); parseGraphQLSchema.addGraphQLType(signUpMutation.type, true, true); parseGraphQLSchema.addGraphQLMutation('signUp', signUpMutation, true, true); + console.log( + 'Class', + parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType._fields + ); + 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: 'UserLoginWihInput', + fields: () => { + const classGraphQLCreateFields = parseGraphQLSchema.parseClassTypes[ + '_User' + ].classGraphQLCreateType._fields() + Object.keys( + parseGraphQLSchema.parseClassTypes[ + '_User' + ].classGraphQLCreateType._fields() + ).reduce((fields, fieldName) => { + if ( + fieldName !== 'password' && + fieldName !== 'username' && + fieldName !== 'authData' + ) { + fields[fieldName] = + parseGraphQLSchema.parseClassTypes[ + '_User' + ].classGraphQLCreateType._fields[fieldName]; + } + console.log(fields); + 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', From cf0d4dff98d269d1f9b45867fb2f39c708f5f7f9 Mon Sep 17 00:00:00 2001 From: Antoine Cormouls Date: Mon, 27 Jan 2020 16:46:07 +0100 Subject: [PATCH 3/3] tested --- spec/ParseGraphQLServer.spec.js | 62 ++++++++++++++++++++++++++- src/GraphQL/loaders/usersMutations.js | 46 ++++++++------------ 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index 83c40b9fc4..4ad5249792 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -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(); diff --git a/src/GraphQL/loaders/usersMutations.js b/src/GraphQL/loaders/usersMutations.js index fd5fd92dae..701929677e 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -73,14 +73,10 @@ const load = parseGraphQLSchema => { ); parseGraphQLSchema.addGraphQLType(signUpMutation.type, true, true); parseGraphQLSchema.addGraphQLMutation('signUp', signUpMutation, true, true); - console.log( - 'Class', - parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType._fields - ); const logInWithMutation = mutationWithClientMutationId({ - name: 'LoginWith', + 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.', + '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', @@ -90,29 +86,25 @@ const load = parseGraphQLSchema => { descriptions: 'These are the fields of the user to be created/updated and logged in.', type: new GraphQLInputObjectType({ - name: 'UserLoginWihInput', + name: 'UserLoginWithInput', fields: () => { const classGraphQLCreateFields = parseGraphQLSchema.parseClassTypes[ '_User' - ].classGraphQLCreateType._fields() - Object.keys( - parseGraphQLSchema.parseClassTypes[ - '_User' - ].classGraphQLCreateType._fields() - ).reduce((fields, fieldName) => { - if ( - fieldName !== 'password' && - fieldName !== 'username' && - fieldName !== 'authData' - ) { - fields[fieldName] = - parseGraphQLSchema.parseClassTypes[ - '_User' - ].classGraphQLCreateType._fields[fieldName]; - } - console.log(fields); - return fields; - }, {}), + ].classGraphQLCreateType.getFields(); + return Object.keys(classGraphQLCreateFields).reduce( + (fields, fieldName) => { + if ( + fieldName !== 'password' && + fieldName !== 'username' && + fieldName !== 'authData' + ) { + fields[fieldName] = classGraphQLCreateFields[fieldName]; + } + return fields; + }, + {} + ); + }, }), }, }, @@ -160,7 +152,7 @@ const load = parseGraphQLSchema => { ); parseGraphQLSchema.addGraphQLType(logInWithMutation.type, true, true); parseGraphQLSchema.addGraphQLMutation( - 'loginWith', + 'logInWith', logInWithMutation, true, true