GraphQL: reset password with emailed token (#7290)
* renamed "resetPassword" to "requestResetPassword" & created new "resetPassword" mutation * added new route to handle resetPassword in UsersRouter.js * updated resetPassword test to "requestResetPassword" mutation * updated "resetPassword" mutation args description * changed token arg description to rerun the tests * directly using updatePassword for resetPassword * removed handleResetPassword from UsersRouter.js file * added test case for reset Password * changed mutation names to "resetPassword" & "confirmResetPassword" * changed mutation names in test also
This commit is contained in:
@@ -7083,6 +7083,77 @@ describe('ParseGraphQLServer', () => {
|
||||
expect(result.data.resetPassword.clientMutationId).toEqual(clientMutationId);
|
||||
expect(result.data.resetPassword.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 ConfirmResetPassword($input: ConfirmResetPasswordInput!) {
|
||||
confirmResetPassword(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 = {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -250,6 +251,61 @@ const load = parseGraphQLSchema => {
|
||||
parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true);
|
||||
parseGraphQLSchema.addGraphQLMutation('resetPassword', resetPasswordMutation, true, true);
|
||||
|
||||
const confirmResetPasswordMutation = mutationWithClientMutationId({
|
||||
name: 'ConfirmResetPassword',
|
||||
description:
|
||||
'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',
|
||||
type: new GraphQLNonNull(GraphQLString),
|
||||
},
|
||||
password: {
|
||||
descriptions: 'New password of the user',
|
||||
type: new GraphQLNonNull(GraphQLString),
|
||||
},
|
||||
token: {
|
||||
descriptions: 'Reset token that was emailed to the user',
|
||||
type: new GraphQLNonNull(GraphQLString),
|
||||
},
|
||||
},
|
||||
outputFields: {
|
||||
ok: {
|
||||
description: "It's always true.",
|
||||
type: new GraphQLNonNull(GraphQLBoolean),
|
||||
},
|
||||
},
|
||||
mutateAndGetPayload: async ({ username, password, token }, context) => {
|
||||
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 };
|
||||
},
|
||||
});
|
||||
|
||||
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',
|
||||
description:
|
||||
|
||||
Reference in New Issue
Block a user