Password requirement custom message (#5399)
* Added validationError(custom message) for Password requirement fail * Changed validationError from valodationError in README.md
This commit is contained in:
committed by
Arthur Cinader
parent
1e7cc7ba00
commit
6eaefd95ae
@@ -326,8 +326,9 @@ var server = ParseServer({
|
|||||||
// If both are specified, both checks must pass to accept the password
|
// If both are specified, both checks must pass to accept the password
|
||||||
// 1. a RegExp object or a regex string representing the pattern to enforce
|
// 1. a RegExp object or a regex string representing the pattern to enforce
|
||||||
validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/, // enforce password with at least 8 char with at least 1 lower case, 1 upper case and 1 digit
|
validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/, // enforce password with at least 8 char with at least 1 lower case, 1 upper case and 1 digit
|
||||||
// 2. a callback function to be invoked to validate the password
|
// 2. a callback function to be invoked to validate the password
|
||||||
validatorCallback: (password) => { return validatePassword(password) },
|
validatorCallback: (password) => { return validatePassword(password) },
|
||||||
|
validationError: 'Password must contain at least 1 digit.' // optional error message to be sent instead of the default "Password does not meet the Password Policy requirements." message.
|
||||||
doNotAllowUsername: true, // optional setting to disallow username in passwords
|
doNotAllowUsername: true, // optional setting to disallow username in passwords
|
||||||
maxPasswordAge: 90, // optional setting in days for password expiry. Login fails if user does not reset the password within this period after signup/last reset.
|
maxPasswordAge: 90, // optional setting in days for password expiry. Login fails if user does not reset the password within this period after signup/last reset.
|
||||||
maxPasswordHistory: 5, // optional setting to prevent reuse of previous n passwords. Maximum value that can be specified is 20. Not specifying it or specifying 0 will not enforce history.
|
maxPasswordHistory: 5, // optional setting to prevent reuse of previous n passwords. Maximum value that can be specified is 20. Not specifying it or specifying 0 will not enforce history.
|
||||||
|
|||||||
@@ -667,7 +667,7 @@ describe('Password Policy: ', () => {
|
|||||||
.then(response => {
|
.then(response => {
|
||||||
expect(response.status).toEqual(302);
|
expect(response.status).toEqual(302);
|
||||||
expect(response.text).toEqual(
|
expect(response.text).toEqual(
|
||||||
`Found. Redirecting to http://localhost:8378/1/apps/choose_password?username=user1&token=${token}&id=test&error=Password%20does%20not%20meet%20the%20Password%20Policy%20requirements.&app=passwordPolicy`
|
`Found. Redirecting to http://localhost:8378/1/apps/choose_password?username=user1&token=${token}&id=test&error=Password%20should%20contain%20at%20least%20one%20digit.&app=passwordPolicy`
|
||||||
);
|
);
|
||||||
|
|
||||||
Parse.User.logIn('user1', 'has 1 digit')
|
Parse.User.logIn('user1', 'has 1 digit')
|
||||||
@@ -700,6 +700,7 @@ describe('Password Policy: ', () => {
|
|||||||
emailAdapter: emailAdapter,
|
emailAdapter: emailAdapter,
|
||||||
passwordPolicy: {
|
passwordPolicy: {
|
||||||
validatorPattern: /[0-9]+/, // password should contain at least one digit
|
validatorPattern: /[0-9]+/, // password should contain at least one digit
|
||||||
|
validationError: 'Password should contain at least one digit.',
|
||||||
},
|
},
|
||||||
publicServerURL: 'http://localhost:8378/1',
|
publicServerURL: 'http://localhost:8378/1',
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
@@ -764,6 +765,9 @@ describe('Password Policy: ', () => {
|
|||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
expect(error.code).toEqual(142);
|
expect(error.code).toEqual(142);
|
||||||
|
expect(error.message).toEqual(
|
||||||
|
'Password cannot contain your username.'
|
||||||
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -853,7 +857,7 @@ describe('Password Policy: ', () => {
|
|||||||
.then(response => {
|
.then(response => {
|
||||||
expect(response.status).toEqual(302);
|
expect(response.status).toEqual(302);
|
||||||
expect(response.text).toEqual(
|
expect(response.text).toEqual(
|
||||||
`Found. Redirecting to http://localhost:8378/1/apps/choose_password?username=user1&token=${token}&id=test&error=Password%20does%20not%20meet%20the%20Password%20Policy%20requirements.&app=passwordPolicy`
|
`Found. Redirecting to http://localhost:8378/1/apps/choose_password?username=user1&token=${token}&id=test&error=Password%20cannot%20contain%20your%20username.&app=passwordPolicy`
|
||||||
);
|
);
|
||||||
|
|
||||||
Parse.User.logIn('user1', 'r@nd0m')
|
Parse.User.logIn('user1', 'r@nd0m')
|
||||||
|
|||||||
@@ -611,8 +611,17 @@ RestWrite.prototype._validatePasswordPolicy = function() {
|
|||||||
|
|
||||||
RestWrite.prototype._validatePasswordRequirements = function() {
|
RestWrite.prototype._validatePasswordRequirements = function() {
|
||||||
// check if the password conforms to the defined password policy if configured
|
// check if the password conforms to the defined password policy if configured
|
||||||
const policyError =
|
// If we specified a custom error in our configuration use it.
|
||||||
'Password does not meet the Password Policy requirements.';
|
// Example: "Passwords must include a Capital Letter, Lowercase Letter, and a number."
|
||||||
|
//
|
||||||
|
// This is especially useful on the generic "password reset" page,
|
||||||
|
// as it allows the programmer to communicate specific requirements instead of:
|
||||||
|
// a. making the user guess whats wrong
|
||||||
|
// b. making a custom password reset page that shows the requirements
|
||||||
|
const policyError = this.config.passwordPolicy.validationError
|
||||||
|
? this.config.passwordPolicy.validationError
|
||||||
|
: 'Password does not meet the Password Policy requirements.';
|
||||||
|
const containsUsernameError = 'Password cannot contain your username.';
|
||||||
|
|
||||||
// check whether the password meets the password strength requirements
|
// check whether the password meets the password strength requirements
|
||||||
if (
|
if (
|
||||||
@@ -632,7 +641,7 @@ RestWrite.prototype._validatePasswordRequirements = function() {
|
|||||||
// username is not passed during password reset
|
// username is not passed during password reset
|
||||||
if (this.data.password.indexOf(this.data.username) >= 0)
|
if (this.data.password.indexOf(this.data.username) >= 0)
|
||||||
return Promise.reject(
|
return Promise.reject(
|
||||||
new Parse.Error(Parse.Error.VALIDATION_ERROR, policyError)
|
new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// retrieve the User object using objectId during password reset
|
// retrieve the User object using objectId during password reset
|
||||||
@@ -644,7 +653,10 @@ RestWrite.prototype._validatePasswordRequirements = function() {
|
|||||||
}
|
}
|
||||||
if (this.data.password.indexOf(results[0].username) >= 0)
|
if (this.data.password.indexOf(results[0].username) >= 0)
|
||||||
return Promise.reject(
|
return Promise.reject(
|
||||||
new Parse.Error(Parse.Error.VALIDATION_ERROR, policyError)
|
new Parse.Error(
|
||||||
|
Parse.Error.VALIDATION_ERROR,
|
||||||
|
containsUsernameError
|
||||||
|
)
|
||||||
);
|
);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user