pr comments:
consolidate write operations also tweak test text
This commit is contained in:
@@ -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));
|
||||||
|
|||||||
@@ -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,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user