Comparing version 0.1.1 to 0.1.2
@@ -0,1 +1,38 @@ | ||
var patterns = require("./patterns"); | ||
var creditcard_prefixes = { | ||
amex : [ "34", "37" ], | ||
maestro : [ "5018", "5020", "5038", "5893", "6304", "6759", "6761", "6762", "6763" ], | ||
mastercard : [ "51", "52", "53", "54", "55" ], | ||
discover4 : [ "6011" ], | ||
discover3 : [ "644", "645", "646", "647", "648", "649" ], | ||
discover2 : [ "65" ] | ||
}; | ||
exports.username = function () { | ||
var opts = { | ||
length : 2, | ||
expr : null | ||
}; | ||
var msg = "invalid-username"; | ||
for (var i = 0; i < arguments.length; i++) { | ||
switch (typeof arguments[i]) { | ||
case "string": | ||
msg = arguments[i]; | ||
break; | ||
case "object": | ||
for (var k in arguments[i]) { | ||
opts[k] = arguments[i][k]; | ||
} | ||
break; | ||
} | ||
} | ||
if (opts.expr === null) { | ||
opts.expr = new RegExp("^[a-z_][a-z0-9_\\-]{" + (opts.length - 1) + ",}$", "i"); | ||
} | ||
return patterns.match(opts.expr, "", msg); | ||
}; | ||
exports.password = function (checks, msg) { | ||
@@ -24,1 +61,101 @@ if (!msg) { | ||
}; | ||
exports.creditcard = function () { | ||
var types = [ "amex", "visa", "maestro", "discover", "mastercard" ]; | ||
var msg = "not-valid-creditcard"; | ||
for (var i = 0; i < arguments.length; i++) { | ||
if (Array.isArray(arguments[i])) { | ||
types = arguments[i]; | ||
} else if (typeof arguments[i] == "string") { | ||
msg = arguments[i]; | ||
} | ||
} | ||
return function (v, next) { | ||
if (!v) return next(msg); | ||
v = "" + v; | ||
var ok = false; | ||
// check right now for the possible types | ||
for (var i = 0; i < types.length; i++) { | ||
switch (types[i]) { | ||
case "amex": | ||
if (v.length != 15) break; | ||
ok = (creditcard_prefixes.amex.indexOf(v.substr(0, 2)) >= 0); | ||
break; | ||
case "visa": | ||
if (v.length < 13) break; | ||
if (v.length > 16) break; | ||
ok = (v[0] == "4"); | ||
break; | ||
case "maestro": | ||
if (v.length < 16) break; | ||
if (v.length > 19) break; | ||
ok = (creditcard_prefixes.maestro.indexOf(v.substr(0, 4)) >= 0); | ||
break; | ||
case "mastercard": | ||
if (v.length < 16) break; | ||
if (v.length > 19) break; | ||
ok = (creditcard_prefixes.mastercard.indexOf(v.substr(0, 2)) >= 0); | ||
break; | ||
case "discover": | ||
if (v.length != 16) break; | ||
ok = (creditcard_prefixes.discover4.indexOf(v.substr(0, 4)) >= 0) || | ||
(creditcard_prefixes.discover3.indexOf(v.substr(0, 3)) >= 0) || | ||
(creditcard_prefixes.discover2.indexOf(v.substr(0, 2)) >= 0); | ||
if (!ok) { | ||
var prefix = +v.substr(0, 6); | ||
ok = (!isNaN(prefix) && prefix >= 622126 && prefix <= 622925); | ||
} | ||
break; | ||
case "luhn": | ||
// fallback | ||
ok = true; | ||
break; | ||
} | ||
if (ok) break; | ||
} | ||
if (!ok) { | ||
return next(msg); | ||
} | ||
// it's in one of possible types, let's check Luhn | ||
var check = +v[v.length - 1]; | ||
if (isNaN(check)) { | ||
return next(msg); | ||
} | ||
var digits = v.slice(0, v.length - 1).split(''); | ||
digits.reverse(); | ||
for (var i = 0; i < digits.length; i++) { | ||
digits[i] = +digits[i]; | ||
if (isNaN(digits[i])) { | ||
return next(msg); | ||
} | ||
if (i % 2 === 0) { | ||
digits[i] *= 2; | ||
if (digits[i] > 9) { | ||
digits[i] -= 9; | ||
} | ||
} | ||
} | ||
check += digits.reduce(function (a, b) { return a + b; }); | ||
return next(check % 10 !== 0 ? msg : null); | ||
}; | ||
}; |
@@ -10,3 +10,3 @@ { | ||
], | ||
"version" : "0.1.1", | ||
"version" : "0.1.2", | ||
"license" : "MIT", | ||
@@ -13,0 +13,0 @@ "repository" : "http://github.com/dresende/node-enforce.git", |
@@ -5,3 +5,3 @@ ## Data Validations [![Build Status](https://secure.travis-ci.org/dresende/node-enforce.png?branch=master)](http://travis-ci.org/dresende/node-enforce) | ||
### Enforce | ||
## Enforce | ||
@@ -52,3 +52,3 @@ You can create a list of validations for several properties of an `Object` and then run the checks to | ||
### Validators | ||
## Validators | ||
@@ -59,31 +59,62 @@ All validators accept a `msg` argument at the end. These argument is the error message returned if the | ||
#### `enforce.required([ msg = "required" ])` | ||
### Required | ||
`enforce.required([ msg ])` | ||
Checks if a property is not `null` and not `undefined`. If can be `false`, `0` or `""`. | ||
#### `enforce.notEmptyString([ msg = "empty-string" ])` | ||
### Empty string | ||
`enforce.notEmptyString([ msg ])` | ||
Checks if a property length is not zero. It can actually work with `Array`s. | ||
#### `enforce.lists.inside(Array[, msg = "outside-list" ])` | ||
### Lists | ||
Checks if the property is inside a list of items (the `Array`). | ||
#### Inside a list | ||
#### `enforce.lists.outside(Array[, msg = "inside-list" ])` | ||
`enforce.lists.inside(list[, msg ])` | ||
Checks if the property is not inside a list of items (the `Array`). | ||
Checks if the property is inside a list of items. | ||
#### `enforce.ranges.number(min[, max[, msg = "out-of-range-number" ]])` | ||
#### Outside a list | ||
`enforce.lists.outside(list[, msg ])` | ||
Checks if the property is not inside a list of items. | ||
### Ranges | ||
#### In a number range | ||
`enforce.ranges.number(min[, max[, msg ]])` | ||
Checks if a value is inside a specific range of numbers. Either `min` or `max` can be set to `undefined` meaning | ||
that range side is `Infinity`. | ||
#### `enforce.ranges.length(min[, max[, msg = "out-of-range-length" ]])` | ||
Please note that this does not check for the type of value passed, you can even use this with `Date` objects. | ||
#### In a length range | ||
`enforce.ranges.length(min[, max[, msg ]])` | ||
Does the same as the above but for the `length` property. | ||
#### `enforce.security.password([ checks = "luns6", ]msg = "weak-password")` | ||
### Security | ||
Checks if a value has some types of characters and a minimal length. `checks` has a default string which means: | ||
#### Username | ||
`enforce.security.username([[ opts, ]msg ])` | ||
Checks if a value matches a username format. `opts` is also optional and is an object with the following keys: | ||
- `length`: the minimal length of the username (default = 2) | ||
- `expr`: the regular expression to be used to match a valid username (if not passed, it's built based on the minimal length) | ||
#### Password | ||
`enforce.security.password([[ checks, ]msg ])` | ||
Checks if a value has some types of characters and a minimal length. `checks` has a default string `luns6` which means: | ||
- `l`: lowercase letters | ||
@@ -98,17 +129,35 @@ - `u`: uppercase letters | ||
#### `enforce.patterns.match(pattern, modifiers[, msg = "no-pattern-match" ]) | ||
#### Credit Card | ||
`enforce.security.creditcard([[ types, ] msg ])` | ||
Checks if a value is a valid credit card number. It supports `amex` (American Express), `visa`, `maestro`, `discover` and `mastercard`. | ||
You can change the list of supported cards (`types`) by passing a list with only some of them. You can also pass `luhn` which will ignore card | ||
prefixes and lenght and only pass the number using the Luhn algorithm. | ||
### Patterns | ||
#### Match | ||
`enforce.patterns.match(pattern, modifiers[, msg ])` | ||
Checks if property passes a specific regular expression. You can pass the `pattern` as a `RegExp` object (setting `modifiers` as `null`) | ||
or just pass a regular expression and it will be converted. | ||
#### `enforce.patterns.hexString([ msg = "not-hex-string" ]) | ||
#### Hex string | ||
`enforce.patterns.hexString([ msg ])` | ||
Checks if a property matches a predefined `RegExp` object accepting insensitive hexadecimal characters. | ||
#### `enforce.patterns.email([ msg = "not-valid-email" ]) | ||
`enforce.patterns.email([ msg ])` | ||
Checks if a property matches a predefined `RegExp` object accepting valid e-mail addresses. | ||
#### `enforce.patterns.ipv4([ msg = "not-valid-ipv4" ]) | ||
#### IPv4 | ||
`enforce.patterns.ipv4([ msg ])` | ||
Checks if a property matches a predefined `RegExp` object accepting valid IPv4 address. |
@@ -33,2 +33,46 @@ var should = require("should"); | ||
describe("enforce.security.username()", function () { | ||
var validator = enforce.security.username(); | ||
it("should pass 'a1'", function (done) { | ||
validator('a1', common.checkValidation(done)); | ||
}); | ||
it("should pass 'A1'", function (done) { | ||
validator('A1', common.checkValidation(done)); | ||
}); | ||
it("should pass '_A1'", function (done) { | ||
validator('_A1', common.checkValidation(done)); | ||
}); | ||
it("should not pass 'a'", function (done) { | ||
validator('a', common.checkValidation(done, 'invalid-username')); | ||
}); | ||
describe("width custom error", function () { | ||
var validator = enforce.security.username('custom-error'); | ||
it("should not pass 'a' with 'custom-error'", function (done) { | ||
validator('a', common.checkValidation(done, 'custom-error')); | ||
}); | ||
}); | ||
}); | ||
describe("enforce.security.username({ length: 5 })", function () { | ||
var validator = enforce.security.username({ length: 5 }); | ||
it("should not pass 'a1'", function (done) { | ||
validator('a1', common.checkValidation(done, 'invalid-username')); | ||
}); | ||
it("should not pass 'abcd'", function (done) { | ||
validator('abcd', common.checkValidation(done, 'invalid-username')); | ||
}); | ||
it("should pass 'username'", function (done) { | ||
validator('username', common.checkValidation(done)); | ||
}); | ||
}); | ||
describe("enforce.security.password('ln4')", function () { | ||
@@ -57,1 +101,93 @@ var validator = enforce.security.password('ln4', 'weak'); | ||
}); | ||
describe("enforce.security.creditcard()", function () { | ||
var validator = enforce.security.creditcard(); | ||
it("should pass '4716025001543325' (VISA)", function (done) { | ||
validator('4716025001543325', common.checkValidation(done)); | ||
}); | ||
it("should pass '6011484016942229' (Discover)", function (done) { | ||
validator('6011484016942229', common.checkValidation(done)); | ||
}); | ||
it("should pass '5194162135294737' (Mastercard)", function (done) { | ||
validator('5194162135294737', common.checkValidation(done)); | ||
}); | ||
it("should pass '6304709865953729' (Maestro)", function (done) { | ||
validator('6304709865953729', common.checkValidation(done)); | ||
}); | ||
it("should pass '342106257219198' (American Express)", function (done) { | ||
validator('342106257219198', common.checkValidation(done)); | ||
}); | ||
it("should not pass '342106257219199'", function (done) { | ||
validator('342106257219199', common.checkValidation(done, 'not-valid-creditcard')); | ||
}); | ||
it("should not pass '5194162135294734'", function (done) { | ||
validator('5194162135294734', common.checkValidation(done, 'not-valid-creditcard')); | ||
}); | ||
it("should not pass '6011484019642229'", function (done) { | ||
validator('6011484019642229', common.checkValidation(done, 'not-valid-creditcard')); | ||
}); | ||
it("should not pass '4917972403611992'", function (done) { | ||
validator('4917972403611992', common.checkValidation(done, 'not-valid-creditcard')); | ||
}); | ||
}); | ||
describe("enforce.security.creditcard([ 'amex' ], 'not-valid')", function () { | ||
var validator = enforce.security.creditcard([ 'amex' ], 'not-valid'); | ||
it("should pass '342106257219198' (American Express)", function (done) { | ||
validator('342106257219198', common.checkValidation(done)); | ||
}); | ||
it("should not pass '4716025001543325' (VISA) with 'not-valid'", function (done) { | ||
validator('4716025001543325', common.checkValidation(done, 'not-valid')); | ||
}); | ||
}); | ||
describe("enforce.security.creditcard([ 'visa' ], 'not-valid')", function () { | ||
var validator = enforce.security.creditcard([ 'visa' ], 'not-valid'); | ||
it("should pass '4716025001543325' (VISA)", function (done) { | ||
validator('4716025001543325', common.checkValidation(done)); | ||
}); | ||
it("should not pass '342106257219198' (American Express) with 'not-valid'", function (done) { | ||
validator('342106257219198', common.checkValidation(done, 'not-valid')); | ||
}); | ||
}); | ||
describe("enforce.security.creditcard([ 'maestro', 'discover' ], 'not-valid')", function () { | ||
var validator = enforce.security.creditcard([ 'maestro', 'discover' ], 'not-valid'); | ||
it("should pass '5038328991436353' (Maestro)", function (done) { | ||
validator('5038328991436353', common.checkValidation(done)); | ||
}); | ||
it("should pass '6011734449679115' (Discover)", function (done) { | ||
validator('6011734449679115', common.checkValidation(done)); | ||
}); | ||
it("should not pass '4485227446136769' (VISA) with 'not-valid'", function (done) { | ||
validator('4485227446136769', common.checkValidation(done, 'not-valid')); | ||
}); | ||
}); | ||
describe("enforce.security.creditcard([ 'luhn' ], 'not-valid')", function () { | ||
var validator = enforce.security.creditcard([ 'luhn' ], 'not-valid'); | ||
it("should pass '12344' (Luhn)", function (done) { | ||
validator('12344', common.checkValidation(done)); | ||
}); | ||
it("should not pass '12345' with 'not-valid'", function (done) { | ||
validator('12345', common.checkValidation(done, 'not-valid')); | ||
}); | ||
}); |
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
38711
962
160