Add support for regex string for password policy validatorPattern setting (#3331)
This commit is contained in:
committed by
Arthur Cinader
parent
df029b82eb
commit
f331f6644c
@@ -281,7 +281,7 @@ var server = ParseServer({
|
|||||||
passwordPolicy: {
|
passwordPolicy: {
|
||||||
// Two optional settings to enforce strong passwords. Either one or both can be specified.
|
// Two optional settings to enforce strong passwords. Either one or both can be specified.
|
||||||
// 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 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) },
|
||||||
|
|||||||
@@ -147,14 +147,14 @@ describe("Password Policy: ", () => {
|
|||||||
reconfigureServer({
|
reconfigureServer({
|
||||||
appName: 'passwordPolicy',
|
appName: 'passwordPolicy',
|
||||||
passwordPolicy: {
|
passwordPolicy: {
|
||||||
validatorPattern: "abc" // string is not a valid setting
|
validatorPattern: 1234 // number is not a valid setting
|
||||||
},
|
},
|
||||||
publicServerURL: "http://localhost:8378/1"
|
publicServerURL: "http://localhost:8378/1"
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
fail('passwordPolicy.validatorPattern type test failed');
|
fail('passwordPolicy.validatorPattern type test failed');
|
||||||
done();
|
done();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
expect(err).toEqual('passwordPolicy.validatorPattern must be a RegExp.');
|
expect(err).toEqual('passwordPolicy.validatorPattern must be a regex string or RegExp object.');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -197,6 +197,28 @@ describe("Password Policy: ", () => {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('signup should fail if password does not conform to the policy enforced using validatorPattern string', (done) => {
|
||||||
|
const user = new Parse.User();
|
||||||
|
reconfigureServer({
|
||||||
|
appName: 'passwordPolicy',
|
||||||
|
passwordPolicy: {
|
||||||
|
validatorPattern: "^.{8,}" // password should contain at least 8 char
|
||||||
|
},
|
||||||
|
publicServerURL: "http://localhost:8378/1"
|
||||||
|
}).then(() => {
|
||||||
|
user.setUsername("user1");
|
||||||
|
user.setPassword("less");
|
||||||
|
user.set('email', 'user1@parse.com');
|
||||||
|
user.signUp().then(() => {
|
||||||
|
fail('Should have failed as password does not conform to the policy.');
|
||||||
|
done();
|
||||||
|
}).catch((error) => {
|
||||||
|
expect(error.code).toEqual(142);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
it('signup should succeed if password conforms to the policy enforced using validatorPattern', (done) => {
|
it('signup should succeed if password conforms to the policy enforced using validatorPattern', (done) => {
|
||||||
const user = new Parse.User();
|
const user = new Parse.User();
|
||||||
reconfigureServer({
|
reconfigureServer({
|
||||||
@@ -231,6 +253,40 @@ describe("Password Policy: ", () => {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('signup should succeed if password conforms to the policy enforced using validatorPattern string', (done) => {
|
||||||
|
const user = new Parse.User();
|
||||||
|
reconfigureServer({
|
||||||
|
appName: 'passwordPolicy',
|
||||||
|
passwordPolicy: {
|
||||||
|
validatorPattern: "[!@#$]+" // password should contain at least one special char
|
||||||
|
},
|
||||||
|
publicServerURL: "http://localhost:8378/1"
|
||||||
|
}).then(() => {
|
||||||
|
user.setUsername("user1");
|
||||||
|
user.setPassword("p@sswrod");
|
||||||
|
user.set('email', 'user1@parse.com');
|
||||||
|
user.signUp().then(() => {
|
||||||
|
Parse.User.logOut().then(() => {
|
||||||
|
Parse.User.logIn("user1", "p@sswrod").then(function () {
|
||||||
|
done();
|
||||||
|
}).catch((err) => {
|
||||||
|
jfail(err);
|
||||||
|
fail("Should be able to login");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
jfail(error);
|
||||||
|
fail('logout should have succeeded');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
jfail(error);
|
||||||
|
fail('Signup should have succeeded as password conforms to the policy.');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
it('signup should fail if password does not conform to the policy enforced using validatorCallback', (done) => {
|
it('signup should fail if password does not conform to the policy enforced using validatorCallback', (done) => {
|
||||||
const user = new Parse.User();
|
const user = new Parse.User();
|
||||||
reconfigureServer({
|
reconfigureServer({
|
||||||
@@ -409,12 +465,12 @@ describe("Password Policy: ", () => {
|
|||||||
fail("should login with new password");
|
fail("should login with new password");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}).catch((error)=> {
|
}).catch((error) => {
|
||||||
jfail(error);
|
jfail(error);
|
||||||
fail("Failed to POST request password reset");
|
fail("Failed to POST request password reset");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
}).catch((error)=> {
|
}).catch((error) => {
|
||||||
jfail(error);
|
jfail(error);
|
||||||
fail("Failed to get the reset link");
|
fail("Failed to get the reset link");
|
||||||
done();
|
done();
|
||||||
@@ -839,7 +895,7 @@ describe("Password Policy: ", () => {
|
|||||||
reconfigureServer({
|
reconfigureServer({
|
||||||
appName: 'passwordPolicy',
|
appName: 'passwordPolicy',
|
||||||
passwordPolicy: {
|
passwordPolicy: {
|
||||||
maxPasswordAge: 0.5/(24*60*60) // 0.5 sec
|
maxPasswordAge: 0.5 / (24 * 60 * 60) // 0.5 sec
|
||||||
},
|
},
|
||||||
publicServerURL: "http://localhost:8378/1"
|
publicServerURL: "http://localhost:8378/1"
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
@@ -880,7 +936,7 @@ describe("Password Policy: ", () => {
|
|||||||
reconfigureServer({
|
reconfigureServer({
|
||||||
appName: 'passwordPolicy',
|
appName: 'passwordPolicy',
|
||||||
passwordPolicy: {
|
passwordPolicy: {
|
||||||
maxPasswordAge: 0.5/(24*60*60) // 0.5 sec
|
maxPasswordAge: 0.5 / (24 * 60 * 60) // 0.5 sec
|
||||||
},
|
},
|
||||||
publicServerURL: "http://localhost:8378/1"
|
publicServerURL: "http://localhost:8378/1"
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
@@ -979,7 +1035,7 @@ describe("Password Policy: ", () => {
|
|||||||
appName: 'passwordPolicy',
|
appName: 'passwordPolicy',
|
||||||
emailAdapter: emailAdapter,
|
emailAdapter: emailAdapter,
|
||||||
passwordPolicy: {
|
passwordPolicy: {
|
||||||
maxPasswordAge: 0.5/(24*60*60) // 0.5 sec
|
maxPasswordAge: 0.5 / (24 * 60 * 60) // 0.5 sec
|
||||||
},
|
},
|
||||||
publicServerURL: "http://localhost:8378/1"
|
publicServerURL: "http://localhost:8378/1"
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
|||||||
@@ -127,10 +127,16 @@ export class Config {
|
|||||||
throw 'passwordPolicy.resetTokenValidityDuration must be a positive number';
|
throw 'passwordPolicy.resetTokenValidityDuration must be a positive number';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(passwordPolicy.validatorPattern && !(passwordPolicy.validatorPattern instanceof RegExp)) {
|
if(passwordPolicy.validatorPattern){
|
||||||
throw 'passwordPolicy.validatorPattern must be a RegExp.';
|
if(typeof(passwordPolicy.validatorPattern) === 'string') {
|
||||||
|
passwordPolicy.validatorPattern = new RegExp(passwordPolicy.validatorPattern);
|
||||||
|
}
|
||||||
|
else if(!(passwordPolicy.validatorPattern instanceof RegExp)){
|
||||||
|
throw 'passwordPolicy.validatorPattern must be a regex string or RegExp object.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(passwordPolicy.validatorCallback && typeof passwordPolicy.validatorCallback !== 'function') {
|
if(passwordPolicy.validatorCallback && typeof passwordPolicy.validatorCallback !== 'function') {
|
||||||
throw 'passwordPolicy.validatorCallback must be a function.';
|
throw 'passwordPolicy.validatorCallback must be a function.';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user