Comparing version 1.1.3 to 1.1.4
@@ -13,2 +13,7 @@ 'use strict'; | ||
const lowercase = /[a-z]/; | ||
const uppercase = /[A-Z]/; | ||
const number = /[\d]/; | ||
const special = /[ -/:-@[-`{-~]/; | ||
module.exports = (joi) => { | ||
@@ -147,11 +152,11 @@ return { | ||
password: { | ||
method(rules = {}) { | ||
let min = rules.min; | ||
let max = rules.max; | ||
return this.min(min).max(max).$_addRule({ name: 'password', args: { rules } }); | ||
method(policy = {}) { | ||
let min = policy.min || 8; | ||
let max = policy.max || 24; | ||
return this.min(min).max(max).$_addRule({ name: 'password', args: { policy } }); | ||
}, | ||
args: [ | ||
{ | ||
name: 'rules', | ||
assert: (value) => Object.keys(value).length > 0, | ||
name: 'policy', | ||
assert: (value) => typeof value === 'object' && !Array.isArray(value), | ||
message: 'must be an object' | ||
@@ -161,32 +166,56 @@ } | ||
validate: (value, helpers, args, options) => { | ||
let rules = args.rules; | ||
let regex = '^'; | ||
let message = 'must contains at least'; | ||
if (!password.test(value)) { | ||
return helpers.error('string.password', { message: 'contains illegal characters' }); | ||
} | ||
if (rules.lowercase) { | ||
regex += '(?=.*[a-z])'; | ||
let policy = args.policy; | ||
let requirement = 0; | ||
let count = 0; | ||
let message = ''; | ||
let error = false; | ||
if (policy.lowercase) { | ||
requirement++; | ||
message += ' one lowercase character,'; | ||
if (lowercase.test(value)) { | ||
count++; | ||
} | ||
} | ||
if (rules.uppercase) { | ||
regex += '(?=.*[A-Z])'; | ||
if (policy.uppercase) { | ||
requirement++; | ||
message += ' one uppercase character,'; | ||
if (uppercase.test(value)) { | ||
count++; | ||
} | ||
} | ||
if (rules.number) { | ||
regex += '(?=.*\\d)'; | ||
if (policy.number) { | ||
requirement++; | ||
message += ' one numeric character,'; | ||
if (number.test(value)) { | ||
count++; | ||
} | ||
} | ||
if (rules.special) { | ||
regex += '(?=.*[ -/:-@[-`{-~])'; | ||
if (policy.special) { | ||
requirement++; | ||
message += ' one special character,'; | ||
if (special.test(value)) { | ||
count++; | ||
} | ||
} | ||
regex += '.*$'; | ||
message = message.slice(0, -1); | ||
regex = new RegExp(regex); | ||
if (!regex.test(value)) { | ||
if (policy.count && policy.count > 0 && policy.count < requirement) { | ||
if (policy.count > count) { | ||
error = true; | ||
message = ` ${policy.count} of the ${requirement} requirements:` + message; | ||
} | ||
} else if (count !== requirement) { | ||
error = true; | ||
} | ||
if (error) { | ||
message = 'must contains at least' + message; | ||
return helpers.error('string.password', { message }); | ||
} | ||
if (!password.test(value)) { | ||
return helpers.error('string.password', { message: 'contains illegal characters' }); | ||
} | ||
return value; | ||
@@ -193,0 +222,0 @@ } |
{ | ||
"name": "joi-plus", | ||
"version": "1.1.3", | ||
"version": "1.1.4", | ||
"description": "Joi with extra rules for string and array.", | ||
@@ -5,0 +5,0 @@ "repository": "git://github.com/flamehamster/joi-plus", |
@@ -17,3 +17,3 @@ # Joi-Plus | ||
* Joi.string().sanitize(function) | ||
* sanitize string using the function that takes a string as a parameter. | ||
* sanitize string using function that takes a string as a parameter. | ||
* returns sanitize string | ||
@@ -33,4 +33,13 @@ | ||
* Joi.string().password(rules) | ||
* Requires the string value to match rules. | ||
* Joi.string().password(policy) | ||
* Requires the string value to match policy. | ||
* policy.min - password minimum length, default 8. | ||
* policy.max - password maximum length, default 24. | ||
* policy.lowercase - if true, password requires lowercase. | ||
* policy.uppercase - if true, password requires uppercase. | ||
* policy.number - if true, password requires number. | ||
* policy.special - if true, password requires special character. | ||
* policy.count | ||
* If defined, password is required to pass the number of requirements. | ||
* If undefined, password is required to pass all of requirements. | ||
@@ -83,3 +92,4 @@ * Joi.string().match(reference) | ||
number: true, | ||
special: true | ||
special: true, | ||
count: 3 | ||
}) | ||
@@ -123,7 +133,8 @@ .required(), | ||
* at least 8 characters long but no more than 120 | ||
* must contains at least one lowercase character | ||
* must contains at least one uppercase character | ||
* must contains at least one numeric character | ||
* must contains at least one special character | ||
* _space_ ! " # $ % & ' ( ) * + , - . : ; < = > ? @ [ \ ] ^ _ \` { | } ~ | ||
* must contain at least 3 of the 4 requirements | ||
* one lowercase character | ||
* one uppercase character | ||
* one numeric character | ||
* one special character | ||
* _space_ ! " # $ % & ' ( ) * + , - . : ; < = > ? @ [ \ ] ^ _ \` { | } ~ | ||
* `repeat_password` | ||
@@ -130,0 +141,0 @@ * a required string |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19787
9
333
185