Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Password requirements message #4582

Closed
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,8 @@ var server = ParseServer({
// 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
// 2. a callback function to be invoked to validate the password
validatorCallback: (password) => { return validatePassword(password) },
validatorCallback: (password) => { return validatePassword(password) },
passwordRequirementsHumanErrorMessage: 'Password must contain a capital letter, lowercase letter, a number and be at least 8 characters long.', //This error message is sent instead of the generic "Password does not meet the Password Policy requirements." message.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we rename to validationError ?

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.
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.
Expand Down
18 changes: 15 additions & 3 deletions src/RestWrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,19 @@ RestWrite.prototype._validatePasswordPolicy = function() {

RestWrite.prototype._validatePasswordRequirements = function() {
// check if the password conforms to the defined password policy if configured
const policyError = 'Password does not meet the Password Policy requirements.';
let containsUsernameError = 'Password cannot contain your username.';
let policyError = 'Password does not meet the Password Policy requirements.';

if(this.config.passwordPolicy.passwordRequirementsHumanErrorMessage){
// If we specified a custom error in our configuration use it.
// Example: "Passwords must include a Capital Letter, Lowercase Letter, and a number."
//
// This is expesially 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
policyError = this.config.passwordPolicy.passwordRequirementsHumanErrorMessage;
}

// check whether the password meets the password strength requirements
if (this.config.passwordPolicy.patternValidator && !this.config.passwordPolicy.patternValidator(this.data.password) ||
Expand All @@ -496,15 +508,15 @@ RestWrite.prototype._validatePasswordRequirements = function() {
if (this.config.passwordPolicy.doNotAllowUsername === true) {
if (this.data.username) { // username is not passed during password reset
if (this.data.password.indexOf(this.data.username) >= 0)
return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, policyError));
return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError));
} else { // retrieve the User object using objectId during password reset
return this.config.database.find('_User', {objectId: this.objectId()})
.then(results => {
if (results.length != 1) {
throw undefined;
}
if (this.data.password.indexOf(results[0].username) >= 0)
return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, policyError));
return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError));
return Promise.resolve();
});
}
Expand Down