Regenerate Email Verification Token on Email Request (#4439)

* regenerate email verification token & expiration in /verificationEmailRequest

* Remove password field when saving on postgres
This commit is contained in:
Benjamin Wilson Friedman
2018-02-01 15:35:08 -08:00
committed by Florent Vilmart
parent f2e21b0538
commit db8594dd33
3 changed files with 48 additions and 11 deletions

View File

@@ -487,6 +487,7 @@ describe("Email Verification Token Expiration: ", () => {
var user = new Parse.User(); var user = new Parse.User();
var sendEmailOptions; var sendEmailOptions;
var sendVerificationEmailCallCount = 0; var sendVerificationEmailCallCount = 0;
let userBeforeRequest;
var emailAdapter = { var emailAdapter = {
sendVerificationEmail: options => { sendVerificationEmail: options => {
sendEmailOptions = options; sendEmailOptions = options;
@@ -509,6 +510,15 @@ describe("Email Verification Token Expiration: ", () => {
return user.signUp(); return user.signUp();
}) })
.then(() => { .then(() => {
const config = Config.get('test');
return config.database.find('_User', {username: 'resends_verification_token'}).then((results) => {
return results[0];
});
})
.then((newUser) => {
// store this user before we make our email request
userBeforeRequest = newUser;
expect(sendVerificationEmailCallCount).toBe(1); expect(sendVerificationEmailCallCount).toBe(1);
return requestp.post({ return requestp.post({
@@ -523,13 +533,25 @@ describe("Email Verification Token Expiration: ", () => {
json: true, json: true,
resolveWithFullResponse: true, resolveWithFullResponse: true,
simple: false // this promise is only rejected if the call itself failed simple: false // this promise is only rejected if the call itself failed
}) });
.then((response) => { })
expect(response.statusCode).toBe(200); .then((response) => {
expect(sendVerificationEmailCallCount).toBe(2); expect(response.statusCode).toBe(200);
expect(sendEmailOptions).toBeDefined(); expect(sendVerificationEmailCallCount).toBe(2);
done(); expect(sendEmailOptions).toBeDefined();
});
// query for this user again
const config = Config.get('test');
return config.database.find('_User', {username: 'resends_verification_token'}).then((results) => {
return results[0];
});
})
.then((userAfterRequest) => {
// verify that our token & expiration has been changed for this new request
expect(typeof userAfterRequest).toBe('object');
expect(userBeforeRequest._email_verify_token).not.toEqual(userAfterRequest._email_verify_token);
expect(userBeforeRequest._email_verify_token_expires_at).not.toEqual(userAfterRequest.__email_verify_token_expires_at);
done();
}) })
.catch(error => { .catch(error => {
jfail(error); jfail(error);

View File

@@ -135,13 +135,23 @@ export class UserController extends AdaptableController {
}); });
} }
/**
* Regenerates the given user's email verification token
*
* @param user
* @returns {*}
*/
regenerateEmailVerifyToken(user) {
this.setEmailVerifyToken(user);
return this.config.database.update('_User', { username: user.username }, user);
}
resendVerificationEmail(username) { resendVerificationEmail(username) {
return this.getUserIfNeeded({username: username}).then((aUser) => { return this.getUserIfNeeded({username: username}).then((aUser) => {
if (!aUser || aUser.emailVerified) { if (!aUser || aUser.emailVerified) {
throw undefined; throw undefined;
} }
this.setEmailVerifyToken(aUser); return this.regenerateEmailVerifyToken(aUser).then(() => {
return this.config.database.update('_User', {username}, aUser).then(() => {
this.sendVerificationEmail(aUser); this.sendVerificationEmail(aUser);
}); });
}); });

View File

@@ -268,14 +268,19 @@ export class UsersRouter extends ClassesRouter {
throw new Parse.Error(Parse.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`); throw new Parse.Error(Parse.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`);
} }
const user = results[0]; const user = results[0];
// remove password field, messes with saving on postgres
delete user.password;
if (user.emailVerified) { if (user.emailVerified) {
throw new Parse.Error(Parse.Error.OTHER_CAUSE, `Email ${email} is already verified.`); throw new Parse.Error(Parse.Error.OTHER_CAUSE, `Email ${email} is already verified.`);
} }
const userController = req.config.userController; const userController = req.config.userController;
userController.sendVerificationEmail(user); return userController.regenerateEmailVerifyToken(user).then(() => {
return { response: {} }; userController.sendVerificationEmail(user);
return { response: {} };
});
}); });
} }