From 53e152e97535d256248a02a22c84f4d7c34d18a5 Mon Sep 17 00:00:00 2001 From: Carmen Date: Tue, 22 Mar 2016 19:08:25 +0800 Subject: [PATCH 1/4] Instead of executing write directly, reuse rest.update to fix request object in user before save is empty when reset password. #951 --- src/Controllers/UserController.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Controllers/UserController.js b/src/Controllers/UserController.js index 1581a659..97cc35aa 100644 --- a/src/Controllers/UserController.js +++ b/src/Controllers/UserController.js @@ -2,6 +2,7 @@ import { randomString } from '../cryptoUtils'; import { inflate } from '../triggers'; import AdaptableController from './AdaptableController'; import MailAdapter from '../Adapters/Email/MailAdapter'; +import rest from '../rest'; var DatabaseAdapter = require('../DatabaseAdapter'); var RestWrite = require('../RestWrite'); @@ -165,8 +166,8 @@ export class UserController extends AdaptableController { } updatePassword(username, token, password, config) { - return this.checkResetTokenValidity(username, token).then(() => { - return updateUserPassword(username, token, password, this.config); + return this.checkResetTokenValidity(username, token).then((user) => { + return updateUserPassword(user._id, password, this.config); }); } @@ -192,12 +193,11 @@ export class UserController extends AdaptableController { } // Mark this private -function updateUserPassword(username, token, password, config) { - var write = new RestWrite(config, Auth.master(config), '_User', { - username: username, - _perishable_token: token - }, {password: password, _perishable_token: null }, undefined); - return write.execute(); +function updateUserPassword(userId, password, config) { + return rest.update(config, Auth.master(config), '_User', userId, { + password: password, + _perishable_token: null + }); } export default UserController; From b3c5e836d55e08b4c36151685e71202a157aaf5a Mon Sep 17 00:00:00 2001 From: Carmen Date: Tue, 22 Mar 2016 20:26:38 +0800 Subject: [PATCH 2/4] Clear reset password token after reset password. `_perishable_token` is not a parse field, cannot clear it through rest. Update it separately. #951 --- src/Controllers/UserController.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Controllers/UserController.js b/src/Controllers/UserController.js index 97cc35aa..d4e3355e 100644 --- a/src/Controllers/UserController.js +++ b/src/Controllers/UserController.js @@ -168,7 +168,15 @@ export class UserController extends AdaptableController { updatePassword(username, token, password, config) { return this.checkResetTokenValidity(username, token).then((user) => { return updateUserPassword(user._id, password, this.config); - }); + }).then(() => { + // clear reset password token + return this.config.database.adaptiveCollection('_User').then(function (collection) { + // Need direct database access because verification token is not a parse field + return collection.findOneAndUpdate({ username: username },// query + { $set: { _perishable_token: null } } // update + ); + }); + }); } defaultVerificationEmail({link, user, appName, }) { @@ -195,8 +203,7 @@ export class UserController extends AdaptableController { // Mark this private function updateUserPassword(userId, password, config) { return rest.update(config, Auth.master(config), '_User', userId, { - password: password, - _perishable_token: null + password: password }); } From 120c6feb6189f039e15b7c599b043b495db30ed7 Mon Sep 17 00:00:00 2001 From: Carmen Date: Tue, 22 Mar 2016 22:20:36 +0800 Subject: [PATCH 3/4] Unset `_perishable_token` after reset password, instead of setting it to null. #951 --- src/Controllers/UserController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/UserController.js b/src/Controllers/UserController.js index d4e3355e..051ddebc 100644 --- a/src/Controllers/UserController.js +++ b/src/Controllers/UserController.js @@ -173,7 +173,7 @@ export class UserController extends AdaptableController { return this.config.database.adaptiveCollection('_User').then(function (collection) { // Need direct database access because verification token is not a parse field return collection.findOneAndUpdate({ username: username },// query - { $set: { _perishable_token: null } } // update + { $unset: { _perishable_token: null } } // update ); }); }); From 603bf97c0b672b12e181a7a17601b9f6750fac35 Mon Sep 17 00:00:00 2001 From: Carmen Date: Wed, 23 Mar 2016 17:27:44 +0800 Subject: [PATCH 4/4] Add test case for checking _perishable_token, it should be unset after password reset. #951 --- spec/ValidationAndPasswordsReset.spec.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/spec/ValidationAndPasswordsReset.spec.js b/spec/ValidationAndPasswordsReset.spec.js index 92d6ecc6..e968ccdf 100644 --- a/spec/ValidationAndPasswordsReset.spec.js +++ b/spec/ValidationAndPasswordsReset.spec.js @@ -573,7 +573,15 @@ describe("Password Reset", () => { expect(response.body).toEqual('Found. Redirecting to http://localhost:8378/1/apps/password_reset_success.html'); Parse.User.logIn("zxcv", "hello").then(function(user){ - done(); + let config = new Config('test'); + config.database.adaptiveCollection('_User') + .then(coll => coll.find({ 'username': 'zxcv' }, { limit: 1 })) + .then((results) => { + // _perishable_token should be unset after reset password + expect(results.length).toEqual(1); + expect(results[0]['_perishable_token']).toEqual(undefined); + done(); + }); }, (err) => { console.error(err); fail("should login with new password");