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.clientMutationId).toEqual(clientMutationId);
|
||||||
expect(result.data.resetPassword.ok).toBeTruthy();
|
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 () => {
|
it('should send verification email again', async () => {
|
||||||
const clientMutationId = uuidv4();
|
const clientMutationId = uuidv4();
|
||||||
const emailAdapter = {
|
const emailAdapter = {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import * as objectsMutations from '../helpers/objectsMutations';
|
|||||||
import { OBJECT } from './defaultGraphQLTypes';
|
import { OBJECT } from './defaultGraphQLTypes';
|
||||||
import { getUserFromSessionToken } from './usersQueries';
|
import { getUserFromSessionToken } from './usersQueries';
|
||||||
import { transformTypes } from '../transformers/mutation';
|
import { transformTypes } from '../transformers/mutation';
|
||||||
|
import Parse from 'parse/node';
|
||||||
|
|
||||||
const usersRouter = new UsersRouter();
|
const usersRouter = new UsersRouter();
|
||||||
|
|
||||||
@@ -250,6 +251,61 @@ const load = parseGraphQLSchema => {
|
|||||||
parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true);
|
parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true);
|
||||||
parseGraphQLSchema.addGraphQLMutation('resetPassword', resetPasswordMutation, 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({
|
const sendVerificationEmailMutation = mutationWithClientMutationId({
|
||||||
name: 'SendVerificationEmail',
|
name: 'SendVerificationEmail',
|
||||||
description:
|
description:
|
||||||
|
|||||||
Reference in New Issue
Block a user