From 12a8d0e13689f3ba3ec467d0cefbd2d580973c66 Mon Sep 17 00:00:00 2001 From: sadakchap Date: Mon, 22 Mar 2021 00:34:06 +0530 Subject: [PATCH 01/10] renamed "resetPassword" to "requestResetPassword" & created new "resetPassword" mutation --- src/GraphQL/loaders/usersMutations.js | 60 +++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/src/GraphQL/loaders/usersMutations.js b/src/GraphQL/loaders/usersMutations.js index 9c57c851259..09dfba2f92b 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -214,10 +214,10 @@ const load = parseGraphQLSchema => { parseGraphQLSchema.addGraphQLType(logOutMutation.type, true, true); parseGraphQLSchema.addGraphQLMutation('logOut', logOutMutation, true, true); - const resetPasswordMutation = mutationWithClientMutationId({ - name: 'ResetPassword', + const requestResetPasswordMutation = mutationWithClientMutationId({ + name: 'RequestResetPassword', description: - 'The resetPassword mutation can be used to reset the password of an existing user.', + 'The requestResetPassword mutation can be used to reset the password of an existing user.', inputFields: { email: { descriptions: 'Email of the user that should receive the reset email', @@ -246,6 +246,60 @@ const load = parseGraphQLSchema => { }, }); + parseGraphQLSchema.addGraphQLType( + requestResetPasswordMutation.args.input.type.ofType, + true, + true + ); + parseGraphQLSchema.addGraphQLType(requestResetPasswordMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation( + 'requestResetPassword', + requestResetPasswordMutation, + true, + true + ); + + const resetPasswordMutation = mutationWithClientMutationId({ + name: 'ResetPassword', + description: + 'The resetPassword mutation can be used to reset the password of an existing user.', + inputFields: { + username: { + descriptions: 'Username of the user that have received the reset email', + type: new GraphQLNonNull(GraphQLString), + }, + password: { + descriptions: 'New password of the user', + type: new GraphQLNonNull(GraphQLString), + }, + token: { + descriptions: 'Reset email token that was sent to user', + type: new GraphQLNonNull(GraphQLString), + }, + }, + outputFields: { + ok: { + description: "It's always true.", + type: new GraphQLNonNull(GraphQLBoolean), + }, + }, + mutateAndGetPayload: async ({ username, password, token }, context) => { + const { config, auth, info } = context; + await usersRouter.handleResetPassword({ + body: { + username, + password, + token, + }, + config, + auth, + info, + }); + + return { ok: true }; + }, + }); + parseGraphQLSchema.addGraphQLType(resetPasswordMutation.args.input.type.ofType, true, true); parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true); parseGraphQLSchema.addGraphQLMutation('resetPassword', resetPasswordMutation, true, true); From fe201d9e079309eb2331320f03606f290ee747b8 Mon Sep 17 00:00:00 2001 From: sadakchap Date: Mon, 22 Mar 2021 00:35:04 +0530 Subject: [PATCH 02/10] added new route to handle resetPassword in UsersRouter.js --- src/Routers/UsersRouter.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index 7843cf46749..660ec90fd68 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -357,6 +357,30 @@ export class UsersRouter extends ClassesRouter { ); } + handleResetPassword(req) { + const { username, password, token } = req.body; + if (!username) { + throw new Parse.Error(Parse.Error.USERNAME_MISSING, 'you must provide a username'); + } + if (!password) { + throw new Parse.Error(Parse.Error.PASSWORD_MISSING, 'you must provide a password'); + } + if (typeof password !== 'string' || typeof username !== 'string') { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); + } + const userController = req.config.userController; + return userController.updatePassword(username, token, password).then( + () => { + return Promise.resolve({ + response: {}, + }); + }, + err => { + throw err; + } + ); + } + handleVerificationEmailRequest(req) { this._throwOnBadEmailConfig(req); @@ -423,6 +447,9 @@ export class UsersRouter extends ClassesRouter { this.route('POST', '/requestPasswordReset', req => { return this.handleResetRequest(req); }); + this.route('POST', '/resetPassword', req => { + return this.handleResetPassword(req); + }); this.route('POST', '/verificationEmailRequest', req => { return this.handleVerificationEmailRequest(req); }); From f421d7c607b7c588b6f40436ae2bc24f624956ae Mon Sep 17 00:00:00 2001 From: sadakchap Date: Mon, 22 Mar 2021 01:24:57 +0530 Subject: [PATCH 03/10] updated resetPassword test to "requestResetPassword" mutation --- spec/ParseGraphQLServer.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index fc3f5d3d102..805a9344c06 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -7065,8 +7065,8 @@ describe('ParseGraphQLServer', () => { await Parse.User.logOut(); const result = await apolloClient.mutate({ mutation: gql` - mutation ResetPassword($input: ResetPasswordInput!) { - resetPassword(input: $input) { + mutation RequestResetPassword($input: RequestResetPasswordInput!) { + requestResetPassword(input: $input) { clientMutationId ok } @@ -7080,8 +7080,8 @@ describe('ParseGraphQLServer', () => { }, }); - expect(result.data.resetPassword.clientMutationId).toEqual(clientMutationId); - expect(result.data.resetPassword.ok).toBeTruthy(); + expect(result.data.requestResetPassword.clientMutationId).toEqual(clientMutationId); + expect(result.data.requestResetPassword.ok).toBeTruthy(); }); it('should send verification email again', async () => { const clientMutationId = uuidv4(); From 638346a97e54a0ac2c4db1a5b5b146669d5d1b05 Mon Sep 17 00:00:00 2001 From: sadakchap Date: Mon, 22 Mar 2021 01:52:38 +0530 Subject: [PATCH 04/10] updated "resetPassword" mutation args description --- 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 09dfba2f92b..2603cf87217 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -273,7 +273,7 @@ const load = parseGraphQLSchema => { type: new GraphQLNonNull(GraphQLString), }, token: { - descriptions: 'Reset email token that was sent to user', + descriptions: 'Reset email token that was emailed to the user', type: new GraphQLNonNull(GraphQLString), }, }, From 4b0930544579e1cb7d4225323450de58ae1fe98a Mon Sep 17 00:00:00 2001 From: sadakchap Date: Mon, 22 Mar 2021 11:07:43 +0530 Subject: [PATCH 05/10] changed token arg description to rerun the tests --- 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 2603cf87217..9725301c30c 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -273,7 +273,7 @@ const load = parseGraphQLSchema => { type: new GraphQLNonNull(GraphQLString), }, token: { - descriptions: 'Reset email token that was emailed to the user', + descriptions: 'Reset token that was emailed to the user', type: new GraphQLNonNull(GraphQLString), }, }, From 344e139bdea49b9cd35f0bb8edea84e29230c3b9 Mon Sep 17 00:00:00 2001 From: sadakchap Date: Wed, 24 Mar 2021 09:59:32 +0530 Subject: [PATCH 06/10] directly using updatePassword for resetPassword --- src/GraphQL/loaders/usersMutations.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/GraphQL/loaders/usersMutations.js b/src/GraphQL/loaders/usersMutations.js index 9725301c30c..80809601664 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -5,6 +5,7 @@ import * as objectsMutations from '../helpers/objectsMutations'; import { OBJECT } from './defaultGraphQLTypes'; import { getUserFromSessionToken } from './usersQueries'; import { transformTypes } from '../transformers/mutation'; +import Parse from 'parse/node'; const usersRouter = new UsersRouter(); @@ -284,18 +285,19 @@ const load = parseGraphQLSchema => { }, }, mutateAndGetPayload: async ({ username, password, token }, context) => { - const { config, auth, info } = context; - await usersRouter.handleResetPassword({ - body: { - username, - password, - token, - }, - config, - auth, - info, - }); + const { config } = context; + if (!username) { + throw new Parse.Error(Parse.Error.USERNAME_MISSING, 'you must provide a username'); + } + if (!password) { + throw new Parse.Error(Parse.Error.PASSWORD_MISSING, 'you must provide a password'); + } + if (!token) { + throw new Parse.Error(Parse.Error.OTHER_CAUSE, 'you must provide a token'); + } + const userController = config.userController; + await userController.updatePassword(username, token, password); return { ok: true }; }, }); From 0ce94a59e2a42f9fce80bab93c9bc1f426d9caa7 Mon Sep 17 00:00:00 2001 From: sadakchap Date: Wed, 24 Mar 2021 10:00:49 +0530 Subject: [PATCH 07/10] removed handleResetPassword from UsersRouter.js file --- src/Routers/UsersRouter.js | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index 660ec90fd68..7843cf46749 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -357,30 +357,6 @@ export class UsersRouter extends ClassesRouter { ); } - handleResetPassword(req) { - const { username, password, token } = req.body; - if (!username) { - throw new Parse.Error(Parse.Error.USERNAME_MISSING, 'you must provide a username'); - } - if (!password) { - throw new Parse.Error(Parse.Error.PASSWORD_MISSING, 'you must provide a password'); - } - if (typeof password !== 'string' || typeof username !== 'string') { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); - } - const userController = req.config.userController; - return userController.updatePassword(username, token, password).then( - () => { - return Promise.resolve({ - response: {}, - }); - }, - err => { - throw err; - } - ); - } - handleVerificationEmailRequest(req) { this._throwOnBadEmailConfig(req); @@ -447,9 +423,6 @@ export class UsersRouter extends ClassesRouter { this.route('POST', '/requestPasswordReset', req => { return this.handleResetRequest(req); }); - this.route('POST', '/resetPassword', req => { - return this.handleResetPassword(req); - }); this.route('POST', '/verificationEmailRequest', req => { return this.handleVerificationEmailRequest(req); }); From 88912b1a062d722a969a16307be66c8a24fc4a19 Mon Sep 17 00:00:00 2001 From: sadakchap Date: Sat, 27 Mar 2021 01:04:46 +0530 Subject: [PATCH 08/10] added test case for reset Password --- spec/ParseGraphQLServer.spec.js | 71 +++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index 805a9344c06..12d293f195d 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -7083,6 +7083,77 @@ describe('ParseGraphQLServer', () => { expect(result.data.requestResetPassword.clientMutationId).toEqual(clientMutationId); expect(result.data.requestResetPassword.ok).toBeTruthy(); }); + + it('should reset password', async () => { + const clientMutationId = uuidv4(); + let resetPasswordToken; + const emailAdapter = { + sendVerificationEmail: () => {}, + sendPasswordResetEmail: ({ link }) => { + resetPasswordToken = link.split('token=')[1].split('&')[0]; + }, + sendMail: () => {}, + }; + parseServer = await global.reconfigureServer({ + appName: 'test', + emailAdapter: emailAdapter, + publicServerURL: 'http://localhost:13377/parse', + auth: { + myAuth: { + module: global.mockCustomAuthenticator('parse', 'graphql'), + }, + }, + }); + const user = new Parse.User(); + user.setUsername('user1'); + user.setPassword('user1'); + user.setEmail('user1@user1.user1'); + await user.signUp(); + await Parse.User.logOut(); + await Parse.User.requestPasswordReset('user1@user1.user1'); + await apolloClient.mutate({ + mutation: gql` + mutation ResetPassword($input: ResetPasswordInput!) { + resetPassword(input: $input) { + clientMutationId + ok + } + } + `, + variables: { + input: { + clientMutationId, + username: 'user1', + password: 'newPassword', + token: resetPasswordToken, + }, + }, + }); + const result = await apolloClient.mutate({ + mutation: gql` + mutation LogInUser($input: LogInInput!) { + logIn(input: $input) { + clientMutationId + viewer { + sessionToken + } + } + } + `, + variables: { + input: { + clientMutationId, + username: 'user1', + password: 'newPassword', + }, + }, + }); + + expect(result.data.logIn.clientMutationId).toEqual(clientMutationId); + expect(result.data.logIn.viewer.sessionToken).toBeDefined(); + expect(typeof result.data.logIn.viewer.sessionToken).toBe('string'); + }); + it('should send verification email again', async () => { const clientMutationId = uuidv4(); const emailAdapter = { From 5bae516acf11ab07ee2bd3635a9acfccf5b82229 Mon Sep 17 00:00:00 2001 From: sadakchap Date: Sat, 27 Mar 2021 08:03:15 +0530 Subject: [PATCH 09/10] changed mutation names to "resetPassword" & "confirmResetPassword" --- spec/ParseGraphQLServer.spec.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index 12d293f195d..8eb099550c1 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -7065,8 +7065,8 @@ describe('ParseGraphQLServer', () => { await Parse.User.logOut(); const result = await apolloClient.mutate({ mutation: gql` - mutation RequestResetPassword($input: RequestResetPasswordInput!) { - requestResetPassword(input: $input) { + mutation ResetPassword($input: ResetPasswordInput!) { + resetPassword(input: $input) { clientMutationId ok } @@ -7080,8 +7080,8 @@ describe('ParseGraphQLServer', () => { }, }); - expect(result.data.requestResetPassword.clientMutationId).toEqual(clientMutationId); - expect(result.data.requestResetPassword.ok).toBeTruthy(); + expect(result.data.resetPassword.clientMutationId).toEqual(clientMutationId); + expect(result.data.resetPassword.ok).toBeTruthy(); }); it('should reset password', async () => { @@ -7113,8 +7113,8 @@ describe('ParseGraphQLServer', () => { await Parse.User.requestPasswordReset('user1@user1.user1'); await apolloClient.mutate({ mutation: gql` - mutation ResetPassword($input: ResetPasswordInput!) { - resetPassword(input: $input) { + mutation ConfirmResetPassword($input: ConfirmResetPasswordInput!) { + confirmResetPassword(input: $input) { clientMutationId ok } @@ -7148,7 +7148,7 @@ describe('ParseGraphQLServer', () => { }, }, }); - + console.log(result); expect(result.data.logIn.clientMutationId).toEqual(clientMutationId); expect(result.data.logIn.viewer.sessionToken).toBeDefined(); expect(typeof result.data.logIn.viewer.sessionToken).toBe('string'); From c427ca97cef00defd85ea0bf7796c6731531cff7 Mon Sep 17 00:00:00 2001 From: sadakchap Date: Sat, 27 Mar 2021 08:05:48 +0530 Subject: [PATCH 10/10] changed mutation names in test also --- spec/ParseGraphQLServer.spec.js | 2 +- src/GraphQL/loaders/usersMutations.js | 42 +++++++++++++-------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index 8eb099550c1..b8673cbe224 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -7148,7 +7148,7 @@ describe('ParseGraphQLServer', () => { }, }, }); - console.log(result); + expect(result.data.logIn.clientMutationId).toEqual(clientMutationId); expect(result.data.logIn.viewer.sessionToken).toBeDefined(); expect(typeof result.data.logIn.viewer.sessionToken).toBe('string'); diff --git a/src/GraphQL/loaders/usersMutations.js b/src/GraphQL/loaders/usersMutations.js index 80809601664..50cb241b68d 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -215,10 +215,10 @@ const load = parseGraphQLSchema => { parseGraphQLSchema.addGraphQLType(logOutMutation.type, true, true); parseGraphQLSchema.addGraphQLMutation('logOut', logOutMutation, true, true); - const requestResetPasswordMutation = mutationWithClientMutationId({ - name: 'RequestResetPassword', + const resetPasswordMutation = mutationWithClientMutationId({ + name: 'ResetPassword', description: - 'The requestResetPassword mutation can be used to reset the password of an existing user.', + 'The resetPassword mutation can be used to reset the password of an existing user.', inputFields: { email: { descriptions: 'Email of the user that should receive the reset email', @@ -247,23 +247,14 @@ const load = parseGraphQLSchema => { }, }); - parseGraphQLSchema.addGraphQLType( - requestResetPasswordMutation.args.input.type.ofType, - true, - true - ); - parseGraphQLSchema.addGraphQLType(requestResetPasswordMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation( - 'requestResetPassword', - requestResetPasswordMutation, - true, - true - ); + parseGraphQLSchema.addGraphQLType(resetPasswordMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('resetPassword', resetPasswordMutation, true, true); - const resetPasswordMutation = mutationWithClientMutationId({ - name: 'ResetPassword', + const confirmResetPasswordMutation = mutationWithClientMutationId({ + name: 'ConfirmResetPassword', description: - 'The resetPassword mutation can be used to reset the password of an existing user.', + 'The confirmResetPassword mutation can be used to reset the password of an existing user.', inputFields: { username: { descriptions: 'Username of the user that have received the reset email', @@ -302,9 +293,18 @@ const load = parseGraphQLSchema => { }, }); - parseGraphQLSchema.addGraphQLType(resetPasswordMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('resetPassword', resetPasswordMutation, true, true); + parseGraphQLSchema.addGraphQLType( + confirmResetPasswordMutation.args.input.type.ofType, + true, + true + ); + parseGraphQLSchema.addGraphQLType(confirmResetPasswordMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation( + 'confirmResetPassword', + confirmResetPasswordMutation, + true, + true + ); const sendVerificationEmailMutation = mutationWithClientMutationId({ name: 'SendVerificationEmail',