pr comments:

consolidate write operations
also tweak test text
This commit is contained in:
Arthur Cinader
2018-10-09 17:34:04 -07:00
parent 6ebce1832b
commit b3b4461fe2
3 changed files with 42 additions and 49 deletions

View File

@@ -910,7 +910,7 @@ describe('Custom Pages, Email Verification, Password Reset', () => {
}); });
}); });
it('deletes password reset token', done => { it('deletes password reset token on email address change', done => {
reconfigureServer({ reconfigureServer({
appName: 'coolapp', appName: 'coolapp',
publicServerURL: 'http://localhost:1337/1', publicServerURL: 'http://localhost:1337/1',
@@ -929,13 +929,14 @@ describe('Custom Pages, Email Verification, Password Reset', () => {
return user return user
.signUp(null) .signUp(null)
.then(() => Parse.User.requestPasswordReset('test@parse.com')) .then(() => Parse.User.requestPasswordReset('test@parse.com'))
.then(() => config.database.adapter .then(() =>
.find( config.database.adapter.find(
'_User', '_User',
{ fields: {} }, { fields: {} },
{ username: 'zxcv' }, { username: 'zxcv' },
{ limit: 1 } { limit: 1 }
)) )
)
.then(results => { .then(results => {
// validate that there is a token // validate that there is a token
expect(results.length).toEqual(1); expect(results.length).toEqual(1);
@@ -943,18 +944,19 @@ describe('Custom Pages, Email Verification, Password Reset', () => {
user.set('email', 'test2@parse.com'); user.set('email', 'test2@parse.com');
return user.save(); return user.save();
}) })
.then(() => config.database.adapter .then(() =>
.find( config.database.adapter.find(
'_User', '_User',
{ fields: {} }, { fields: {} },
{ username: 'zxcv' }, { username: 'zxcv' },
{ limit: 1 }) { limit: 1 }
)
) )
.then(results => { .then(results => {
expect(results.length).toEqual(1); expect(results.length).toEqual(1);
expect(results[0]['_perishable_token']).toBeUndefined(); expect(results[0]['_perishable_token']).toBeUndefined();
done(); done();
}) });
}) })
.catch(error => { .catch(error => {
fail(JSON.stringify(error)); fail(JSON.stringify(error));

View File

@@ -9,6 +9,15 @@ var RestQuery = require('../RestQuery');
var Auth = require('../Auth'); var Auth = require('../Auth');
export class UserController extends AdaptableController { export class UserController extends AdaptableController {
// Add token delete operations to a rest update object
static addClearPasswordResetTokenToRestObject(restObject) {
const addOps = {
_perishable_token: { __op: 'Delete' },
_perishable_token_expires_at: { __op: 'Delete' },
};
return Object.assign({}, restObject, addOps);
}
constructor(adapter, appId, options = {}) { constructor(adapter, appId, options = {}) {
super(adapter, appId, options); super(adapter, appId, options);
} }
@@ -242,35 +251,17 @@ export class UserController extends AdaptableController {
}); });
} }
clearPasswordResetToken(objectId) {
return this.config.database.update(
'_User',
{ objectId },
{
_perishable_token: { __op: 'Delete' },
_perishable_token_expires_at: { __op: 'Delete' },
}
)
}
updatePassword(username, token, password) { updatePassword(username, token, password) {
return ( return this.checkResetTokenValidity(username, token)
this.checkResetTokenValidity(username, token) .then(user => updateUserPassword(user.objectId, password, this.config))
.then(user => .catch(error => {
Promise.all([ if (error.message) {
updateUserPassword(user.objectId, password, this.config), // in case of Parse.Error, fail with the error message only
this.clearPasswordResetToken(user.objectId) return Promise.reject(error.message);
])) } else {
.then(results => results[0]) return Promise.reject(error);
.catch(error => { }
if (error.message) { });
// in case of Parse.Error, fail with the error message only
return Promise.reject(error.message);
} else {
return Promise.reject(error);
}
})
);
} }
defaultVerificationEmail({ link, user, appName }) { defaultVerificationEmail({ link, user, appName }) {
@@ -314,9 +305,7 @@ function updateUserPassword(userId, password, config) {
Auth.master(config), Auth.master(config),
'_User', '_User',
{ objectId: userId }, { objectId: userId },
{ UserController.addClearPasswordResetTokenToRestObject({ password })
password: password,
}
); );
} }

View File

@@ -105,27 +105,29 @@ export class ClassesRouter extends PromiseRouter {
); );
} }
afterUpdate(req, response) { // always clear password reset token on email address change
if (this.className(req) === '_User' && ('email' in req.body)) { beforeUpdate(req) {
const userController = req.config.userController; const { body } = req;
return userController.clearPasswordResetToken(req.params.objectId) if (this.className(req) === '_User' && 'email' in body) {
.then(() => const { userController } = req.config;
response return userController.constructor.addClearPasswordResetTokenToRestObject(
); body
);
} }
return Promise.resolve(response); return body;
} }
handleUpdate(req) { handleUpdate(req) {
const body = this.beforeUpdate(req);
const where = { objectId: req.params.objectId }; const where = { objectId: req.params.objectId };
return rest.update( return rest.update(
req.config, req.config,
req.auth, req.auth,
this.className(req), this.className(req),
where, where,
req.body, body,
req.info.clientSDK req.info.clientSDK
).then(this.afterUpdate.bind(this, req)); );
} }
handleDelete(req) { handleDelete(req) {