Coder Social home page Coder Social logo

koa-validate's Introduction

koa-validate

Build Status Coverage Status NPM version Dependency Status

NPM

validate koa request params and format request params

Installation

$ npm install koa-validate --save

Basic usage:

'use strict';
var koa = require('koa');
var app = koa();
var router = require('koa-router')();
require('koa-validate')(app);

app.use(require('koa-body')({multipart:true , formidable:{keepExtensions:true}}));
app.use(router.routes()).use(router.allowedMethods());
router.post('/signup', function * () {
	//optional() means this param may not in the params.
	this.checkBody('name').optional().len(2, 20,"are you kidding me?");
	this.checkBody('email').isEmail("your enter a bad email.");
	this.checkBody('password').notEmpty().len(3, 20).md5();
	//empty() mean this param can be a empty string.
	this.checkBody('nick').optional().empty().len(3, 20);
	//also we can get the sanitized value 
	var age = this.checkBody('age').toInt().value;
	yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" , function*(file,context){
		//resize image
	});
	if (this.errors) {
		this.body = this.errors;
		return;
	}
});
router.get('/users', function * () {
	this.checkQuery('department').empty().in(["sale","finance"], "not support this department!").len(3, 20);	
	this.checkQuery('name').empty().len(2,20,"bad name.").trim().toLow();
	this.checkQuery('age').empty().gt(10,"too young!").lt(30,"to old!").toInt();
	if (this.errors) {
		this.body = this.errors;
		return;
	}
});
router.get('/user/:id', function * () {
	this.checkParams('id').toInt(0);
	if (this.errors) {
		this.body = this.errors;
		return;
	}
});
//json body,we can check it using [json path](https://github.com/flitbit/json-path)(like xpath)
router.post('/json' , function*(){
	this.checkBody('/store/book[0]/price').get(0).eq(8.95);
	this.checkBody('#/store/book[0]/category').first().trim().eq('reference');
	if (this.errors) {
		this.body = this.errors;
		return;
	}
})

app.listen(3000);

API

checkBody,checkQuery,checkParams will return a Validator instance. when use require('koa-validate')(app) ,the request context will bind the method:

  • checkBody(fieldName,[transFn]) - check POST body.,transFn see json-path.it will not use json path if transFn is false.
  • checkQuery(fieldName,[transFn]) - check GET query.,transFn see json-path.it will not use json path if transFn is false.
  • checkParams(fieldName) - check the params in the urls.
  • checkFile(fieldName,[deleteOnCheckFailed]) - check the file object, if you use koa-body.this function will return FileValidator object. deleteOnCheckFailed default value is true
  • checkHeader(fieldName) - check the params in the request http header.

Validator API

Access validator status:

  • addError(tip) - add an error to validator errors.
  • hasError() - check if validator has errors.
  • value - the value of current validator.

Validators:

options,version or locale please see validator

  • optional() - the param may not in the params.if the param not exists,it has no error,no matter whether have other checker or not.
  • empty([tip]) - the params can be a empty string.
  • notEmpty([tip]) - check if the param is not empty.
  • notBlank([tip]) - check if the param is not blank,use /^\s*$/gi reg to check.
  • match(pattern,[tip]) - pattern must be a RegExp instance ,eg. /abc/i
  • notMatch(pattern,[tip]) - pattern must be a RegExp instance ,eg. /xyz/i
  • ensure(assertion, [tip], [shouldBail]) if assertion is false,the asserting failed.
  • ensureNot(assertion, [tip], [shouldBail]) if assertion is true,the asserting failed.
  • isInt([tip],[options]) - check if the param is integer.
  • isFloat([tip],[options]) - check if the param is float.
  • isLength(min,[max],[tip]) - check the param length.
  • len(min,[max],[tip]) - the abbreviation of isLength.
  • isIn(arr,[tip]) - check if the param is in the array.
  • in(arr,[tip]) - the abbreviation of isIn.
  • eq(value,[tip]) - check if the param equal to the value.
  • neq(value,[tip]) - check if the param not equal to the value.
  • gt(num,[tip]) - check if the param great then the value.
  • lt(num,[tip]) - check if the param less then the value.
  • ge(num,[tip]) - check if the param great then or equal the value.
  • le(num,[tip]) - check if the param less then or equal the value.
  • contains(str,[tip]) - check if the param contains the str.
  • notContains(str,[tip]) - check if the param not contains the str.
  • isEmail([tip],[options]) - check if the param is an email.
  • isUrl([tip],[options]) - check if the param is an URL.
  • isIp([tip]) - check if the param is an IP (version 4 or 6).
  • isAlpha([tip],[locale]) - check if the param contains only letters (a-zA-Z).
  • isNumeric([tip]) - check if the param contains only numbers.
  • isAlphanumeric([tip],[locale]) - check if the param contains only letters and numbers.
  • isBase64([tip]) - check if a param is base64 encoded.
  • isHexadecimal([tip]) - check if the param is a hexadecimal number.
  • isHexColor([tip]) - check if the param is a hexadecimal color.
  • isLowercase([tip]) - check if the param is lowercase.
  • isUppercase([tip]) - check if the param is uppercase.
  • isDivisibleBy(num,[tip]) - check if the param is a number that's divisible by another.
  • isNull([tip]) - check if the param is null.
  • isByteLength(min,max,[tip]) - check if the param's length (in bytes) falls in a range.
  • byteLength(min,max,[tip]) - the abbreviation of isByteLength.
  • isUUID([tip],[version]) - check if the param is a UUID (version 3, 4 or 5).
  • isDate([tip]) - check if the param is a date.
  • isAfter(date,[tip]) - check if the param is a date that's after the specified date.
  • isBefore(date,[tip]) - check if the param is a date that's before the specified date.
  • isCreditCard([tip]) - check if the param is a credit card.
  • isISBN([tip],version) - check if the param is an ISBN (version 10 or 13).
  • isJSON([tip]) - check if the param is valid JSON (note: uses JSON.parse).
  • isMultibyte([tip]) - check if the param contains one or more multibyte chars.
  • isAscii([tip]) - check if the param contains ASCII chars only.
  • isFullWidth([tip]) - check if the param contains any full-width chars.
  • isHalfWidth([tip]) - check if the param contains any half-width chars.
  • isVariableWidth([tip]) - check if the param contains a mixture of full and half-width chars
  • isSurrogatePair([tip]) - check if the param contains any surrogate pairs chars.
  • isCurrency([tip],[options]) - check if the param is a currency.
  • isDataURI([tip]) - check if the param is a data uri.
  • isMobilePhone([tip],[locale]) - check if the param is a mobile phone.
  • isISO8601([tip]) - check if the param is a ISO8601 string. eg.2004-05-03
  • isMACAddress([tip]) - check if the param is a MAC address.eg.C8:3A:35:CC:ED:80
  • isISIN([tip]) - check if the param is a ISIN.
  • isFQDN([tip],[options]) - check if the param is a fully qualified domain name. eg.www.google.com

Sanitizers:

  • default(value) - if the param not exits or is an empty string, it will take the default value.
  • toDate() - convert param to js Date object.
  • toInt([tip],[radix],[options]) - convert param to integer.radix for toInt,options for isInt.
  • toFloat([tip]) - convert param to float.
  • toLowercase() - convert param to lowercase.
  • toLow() - same as toLowercase.
  • toUppercase() - convert param to uppercase.
  • toUp() - same as toUppercase.
  • toBoolean() - convert the param to a boolean. Everything except for '0', 'false' and '' returns true. In strict mode only '1' and 'true' return true.
  • toJson([tip]) - convert param to json object.
  • trim([chars]) - trim characters (whitespace by default) from both sides of the param.
  • ltrim([chars]) - trim characters from the left-side of the param.
  • rtrim([chars]) - trim characters from the right-side of the param.
  • escape() - replace <, >, & and " with HTML entities.
  • stripLow() - remove characters with a numerical value < 32 and 127, mostly control characters.
  • whitelist(value) - remove characters that do not appear in the whitelist.
  • blacklist(value) - remove characters that appear in the blacklist.
  • encodeURI() - ref mdn encodeURI
  • decodeURI([tip]) - ref mdn decodeURI
  • encodeURIComponent() - ref mdn encodeURIComponent
  • decodeURIComponent([tip]) - ref mdn decodeURIComponent
  • replace(regexp|substr, newSubStr|function) - the same as String replace
  • clone(newKey,[newValue]) - clone current value to the new key, if newValue supplied , use it. eg. this.checkBody('v1').clone('md5').md5(); then your can use this.request.body.md5.
  • encodeBase64() - encode current value to base64 string.
  • decodeBase64([inBuffer],[tip]) - decode current base64 to a normal string,if inBuffer is true , the value will be a Buffer.
  • hash(alg , [encoding]) - hash current value use specified algorithm and encoding(if supplied , default is 'hex'). ref hash
  • md5() - md5 current value into hex string.
  • sha1() - sha1 current value into hex string.

For json path:

  • check(fn,tip,scope) - if fn return false then check failed.fn format function(value,key,requestParams):boolean
  • filter(fn,scope) - filter the value if value is array.fn format function(value,index,key,requestParams):boolean
  • get(index) - change the value to the specified index value
  • first() - get the first value!

FileValidator:

Validators:

  • empty() - current file field can to be a empty file.
  • notEmpty([tip]) - current file field can not to be a empty file.
  • size(min,max,[tip]) - limit the file size.
  • contentTypeMatch(reg,[tip]) - check the file's contentType with regular expression.
  • isImageContentType([tip]) - check the file's contentType if is image content type.
  • fileNameMatch(reg,[tip]) - check the file's name with regular expression.
  • suffixIn(arr,[tip]) - check the suffix of file's if in specified arr. arr eg. ['png','jpg']

Sanitizers:

File sanitizers are generators,we should use yield to execute them. eg. yield this.checkFile('file').notEmpty().copy('/');

  • move(target,[afterMove]) - move upload file to the target location. target can be a string or function or function*.if target end with '/' or '\',the target will be deemed as directory. target function interface:string function(fileObject,fieldName,context).this function will return a string of the target file. afterMove:it can be a function or function*.interface:function(fileObject,fieldName,context)
  • copy(target,[afterCopy]) - move upload file to the target location. target can be a string or function or function*. target function interface:function (fileObject,fieldName,context) . afterCopy:it can be a function or function*.interface:function(fileObject,fieldName,context)
  • delete() - delete upload file.

How to extends validate:

var Validator = require('koa-validate').Validator;
// to do what you want to.
//you can use this.key ,this.value,this.params,this.context,this.exists
//use addError(tip) , if you meet error.

koa-validate's People

Contributors

neonerd avatar rocksonzeta avatar theartoflogic avatar uzoice avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

koa-validate's Issues

Can't use optional with sanitizers.

This is my code

const getValidation = function* (next) {
  this.checkQuery('limit').optional().len(1, 100).trim().toInt()
  this.checkQuery('offset').optional().len(1, 100).trim().toInt()

  if (this.errors) {
    this.status = 400
    this.body = this.errors
    return
  }
  yield next
}

router.get('/something', getValidation, Ctrl.get)

When I send GET without offset query params, It will populate error with TypeError: This library (validator.js) validates strings only. If I did something wrong just point me to correct please. Thank you.

Some helpful validators

Here are some validators I use in my project that I think should belong to koa-validate.

  1. notMatch - inverse of match

  2. ensure - executes arbitrary expression. if falsey, then error. (koa-validate needs a generic validator for arbitrary expressions)

    this.checkBody('username')
      .notEmpty('Username required')
      .ensureNot(yield db.findUserByUsername(this.request.body.username), 'Username taken')
  3. ensureNot (or perhaps refute) - inverse of ensure

Implementations:

// Ensure that a string does not match the supplied regular expression.
Validator.prototype.notMatch = function(reg, tip) {
    if (this.goOn && reg.test(this.value)) {
        this.addError(tip || this.key + ' is bad format.');
    }
    return this;
};

// Ensure that `assertion`, an arbitrary value, is falsey.
Validator.prototype.ensureNot = function(assertion, tip, shouldBail) {
  if (shouldBail) this.goOn = false;
    if (this.goOn && !!assertion) {
        this.addError(tip || this.key + ' failed an assertion.');
    }
    return this;
};

// Ensure that `assertion`, an arbitrary value, is truthy.
Validator.prototype.ensure = function(assertion, tip, shouldBail) {
  if (shouldBail) this.goOn = false;
    if (this.goOn && !assertion) {
        this.addError(tip || this.key + ' failed an assertion.');
    }
    return this;
};

edit: ignore shouldBail

Exporting validator module

Hello,

While I was extending this module with a custom validator function I wanted to use the validator module.

I know that a simple npm install --save validator and require would do the job (which I did) but could be nice to export it or to make it available in the object with a variable like this.v or something else.

it would be better accept option to set error type and structure

i looked into the code ,there is a

// var opt = opt || {};

it would be useful if i can set type of this.errors( which defaults to an array ), so i don't have to modify the "this.error" object to proper handling or logging;

i remember express-validator can do that;

calling toFloat with a number results in TypeError

When calling isFloat, the library checks whether the object is already a number. But when calling toFloat the library doesn't check that, so passing a number to v.toFloat will result in TypeError: This library (validator.js) validates strings only.

It may not be a big problem, since we should know the type of each object before validating.

TypeError Problem: this.checkFile(...).notEmpty(...).size is not a function

I just copied the sample code in read me but got this error:

 TypeError: this.checkFile(...).notEmpty(...).size is not a function
      at Object.<anonymous> (/Applications/MAMP/htdocs/nia/test.js:21:45)
      at next (native)
      at Object.dispatch (/Applications/MAMP/htdocs/nia/node_modules/koa-router/lib/router.js:331:14)
      at next (native)
      at onFulfilled (/Applications/MAMP/htdocs/nia/node_modules/koa/node_modules/co/index.js:65:19)
      at /Applications/MAMP/htdocs/nia/node_modules/koa/node_modules/co/index.js:54:5
      at Object.co (/Applications/MAMP/htdocs/nia/node_modules/koa/node_modules/co/index.js:50:10)
      at Object.toPromise (/Applications/MAMP/htdocs/nia/node_modules/koa/node_modules/co/index.js:118:63)
      at next (/Applications/MAMP/htdocs/nia/node_modules/koa/node_modules/co/index.js:99:29)
      at onFulfilled (/Applications/MAMP/htdocs/nia/node_modules/koa/node_modules/co/index.js:69:7)

Am I missing something? Here is my final code:

'use strict';
var koa = require('koa');
var app = koa();

app.use(require('koa-body')());
app.use(require('koa-validate')());
var router = require('koa-router')();

router.get('/upload', function *(){
    this.body = '<form action="/upload" enctype="multipart/form-data" method="post">'+
    '<input type="text" name="title"><br>'+
    '<input type="file" name="file" ><br>'+
    '<input type="submit" value="Upload">'+
    '</form>'

} );

router.post('/upload', function * () {
    //optional() means this param may not in the params.

    yield this.checkFile('file').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" , function*(file,context){
        //resize image
    });
    if (this.errors) {
        this.body = this.errors;
        return;
    }
    this.body = this.request.body;
});

app
    .use(router.routes())
    //.use(router.allowedMethods());

app.listen(3000);

Is this project still actively maintained?

I am very interested in whether this project is still actively maintained, since it is the most starred validation middleware for koa. I would love to help out and develop some features, but there does not seem to be much activity on reviewing pull request.

Validate sub-elements

Supposed I want to validate a sub-element like:

{address:
  {street: "Millerstreet"}
}

My check

this.checkBody('address.street').notEmpty()

does not seem to work.
Is it even possible to validate sub-elements with koa-validate?
Or have I simply missed something?

If using jsonpath, properties aren't properly marked as existing

When using jsonpath, the library still uses key in body to determine whether given key exists.

return new Validator(this, key, getValue(body,key,transFn), key in body , body);

Therefore, with a body like this:

{"foo":{"bar":"hello world"}}

Following code will return an error:

this.checkBody('/foo/bar', true).first().exist()

Because the property is marked as exists:false.

how are you guys unit testing this?

I know this question may not belong here but I will ask anyway.

In order to test this I have had to use supertest, which is more of an integration test. The problem I am having is trying to figure out how to emulate the 'koa context' in order to test it because the validator is attached to the context in the middleware. I really like this validator and don't want to move to another one, so any suggestions would be great. Thanks!

A type confusion vulnerability can lead in json-ptr

ERROR : This affects the package json-ptr before 3.0.0. A type confusion vulnerability can lead to a when the user-provided keys used in the pointer parameter are arrays.

json-ptr is dependency package for json-path version ^0.1.3 which is again a dependency package for Koa-validate package.

optional doesn't work

image

koa-router writes like above picture

debuginfo
image

image

image

I request via browser
I didn't pass 'id' param, but debuginfo indicates "exists: true", In fact, it doesn't exists. So I think optional method doesn't work!?

I find koa-router docs, find this:
image

so I was confused, please give me some advice? tks

Check is string

how do you check a body parameter is actually string, rather than number or null or object?

feature request: validate an array of object

it would be nice if it possible to validate array of object, for example somebody post something like this:

[
    {
        name:'aa',
        age: 23,
               tags:['ss','2333']
    },
    {
        name:'bb',
        age: 25
    },
]

we can use those code to check each object in an array of even nested array

app.use(function*(){
    // the "$" indicate this field is in an array;
    this.checkBody('$.name').len(2,10);
    this.checkBody('$.age').len(2,10);
    this.checkBody('$.tags.$').len(1,10);

})

Let isLength have 0 has min.

If I want to ensure a parameter is 0-100 chars long with .isLength(0, 100), isn't this line messing that up?

this.notEmpty(tip);

Example: this.checkBody('markup').trim().isLength(0, 100) will always trigger isLength error when { markup: '' }. optional() didn't change anything.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.