Conversation
|
@raymondfeng @bajtos PTAL |
|
@loay let's start with a failing unit test please. |
| if (salt.length < 73) { | ||
| return bcrypt.hashSync(plain, salt); | ||
| } else { | ||
| throw new Error('Validation Error'); |
There was a problem hiding this comment.
Notice that validatePassword provides a helpful error message and HTTP status code 422. We should do the same here.
I don't understand. My expectation is that it should be enough to extend the condition in Having said that, the error should make it clear to the user that they have entered a password that's too long and also what's the maximum allowed length. |
|
As for test coverage, I would like to see the following test cases (at least):
|
74a289e to
422198f
Compare
|
@bajtos Fixed. PTAL |
| return true; | ||
| } | ||
| if (plain.length > MAXLENGTH) { | ||
| err = new Error (g.f('Invalid password exceeds maximum length')); |
There was a problem hiding this comment.
Please include MAXLEN value in the message.
g.f('Password too long - maximum length is %s', MAXLEN);| describe('Password validation with Maxlength', function() { | ||
| var pass72 = 'ThePasswordShouldNotExceedtheMaximumNumberOfcharactersAndItisInvalidIfIt'; | ||
| var pass73 = 'ThePasswordShouldNotExceedtheMaximumNumberOfcharactersAndItisInvalidIfIt1'; | ||
| var badPass = 'ThePasswordShouldNotExceedtheMaximumNumberOfcharactersAndItisInvalidIfItXYZ1'; |
There was a problem hiding this comment.
Might be more accurate to use Array(72).join('a') or something to represent N chars.
And what is the diff between badpass and pass73? I assume they are both bad.
There was a problem hiding this comment.
pass73 is a good password with 73 chars, so the expected behaviour that it cannot be used to neither create nor reset, while badpass is a completely bas password that cannot be used to login after the user is already created.
| } catch (e) { | ||
| expect(e).to.match(/Error: Password too long/); | ||
| done(); | ||
| } |
IMO, this assumption is reasonable. |
| expect(err).to.have.property('message', /Password too long/); | ||
| }); | ||
| } catch (e) { | ||
| expect(e).to.match(/Password too long/); |
There was a problem hiding this comment.
Is Password too long reported via callback or throw? It should be exclusive.
There was a problem hiding this comment.
The issue is validatePassword is throwing and it's bubbling up. However, we should be try/catching internally and returning the error via callback so it's transparent to the end user.
|
@loay IMO, here are the steps remaining steps needed:
Just make sure the final commit message mentions the breaking behaviour for password too long.
3a) Fix user methods to catch errors thrown by `validatePassword' @raymondfeng @superkhau is there anything else? |
|
I had a conversation with @bajtos and agreed to simplify the PR as follows:
|
| return cb.promise; | ||
| } | ||
|
|
||
| if (options.password) { |
There was a problem hiding this comment.
What is the options.password for?
|
|
||
| try { | ||
| if (options.password) { | ||
| UserModel.validatePassword(options.password); |
There was a problem hiding this comment.
I have to use options.password because otherwise length will not be defined and will break few other test cases and cause errors. I mean length in main validatePassword function.
There was a problem hiding this comment.
Got it. The new password is passed in as options.password.
There was a problem hiding this comment.
I don't think that's true. resetMethod does not touch the password, it only creates an access token. See also the API docs.
* Create a short lived acess token for temporary login. Allows users * to change passwords if forgotten. * * @options {Object} options * @prop {String} email The user's email address * @callback {Function} callback * @param {Error} err * @promise
Let's not worry about that right now and fix it as part of #382.
There was a problem hiding this comment.
Here is the documentation explaining how to implement password reset: https://github.com/strongloop/loopback-example-user-management#how-do-you-perform-a-password-reset-for-a-registered-user
Gist - the password is updated via user.updateAttribute, which calls user.updateAttributes under the hood IIRC.
User.findById(req.accessToken.userId, function(err, user) {
if (err) return res.sendStatus(404);
user.updateAttribute('password', req.body.password, function(err, user) {|
LGTM |
|
@slnode test please |
connect https://github.com/strongloop-internal/scrum-loopback/issues/994