Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

express-validator

Package Overview
Dependencies
Maintainers
3
Versions
121
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-validator - npm Package Compare versions

Comparing version 5.2.0 to 5.3.0

docs/api-check.md

22

check/check.d.ts

@@ -10,4 +10,4 @@ import * as express from 'express';

export type AlphanumericLocale = 'ar' | 'ar-AE' | 'ar-BH' | 'ar-DZ' | 'ar-EG' | 'ar-IQ' | 'ar-JO' | 'ar-KW' | 'ar-LB' | 'ar-LY' | 'ar-MA' | 'ar-QA' | 'ar-QM' | 'ar-SA' | 'ar-SD' | 'ar-SY' | 'ar-TN' | 'ar-YE' | 'bg-BG' | 'cs-CZ' | 'da-DK' | 'de-DE' | 'el-GR' | 'en-AU' | 'en-GB' | 'en-HK' | 'en-IN' | 'en-NZ' | 'en-US' | 'en-ZA' | 'en-ZM' | 'es-ES' | 'fr-FR' | 'fr-BE' | 'hu-HU' | 'it-IT' | 'nb-NO' | 'nl-BE' | 'nl-NL' | 'nn-NO' | 'pl-PL' | 'pt-BR' | 'pt-PT' | 'ru-RU' | 'sk-SK' | 'sr-RS' | 'sr-RS@latin' | 'sv-SE' | 'tr-TR' | 'uk-UA'
export type MobilePhoneLocal = 'any' | 'ar-AE' | 'ar-DZ' | 'ar-EG' | 'ar-JO' | 'ar-SA' | 'ar-SY' | 'be-BY' | 'bg-BG' | 'cs-CZ' | 'de-DE' | 'da-DK' | 'el-GR' | 'en-AU' | 'en-GB' | 'en-HK' | 'en-IN' | 'en-KE' | 'en-NG' | 'en-NZ' | 'en-PK' | 'en-RW' | 'en-SG' | 'en-TZ' | 'en-UG' | 'en-US' | 'en-CA' | 'en-ZA' | 'en-ZM' | 'es-ES' | 'et-EE' | 'fa-IR' | 'fi-FI' | 'fo-FO' | 'fr-FR' | 'he-IL' | 'hu-HU' | 'id-ID' | 'it-IT' | 'ja-JP' | 'kk-KZ' | 'kl-GL' | 'lt-LT' | 'ms-MY' | 'nb-NO' | 'nn-NO' | 'pl-PL' | 'pt-PT' | 'ro-RO' | 'ru-RU' | 'sk-SK' | 'sr-RS' | 'th-TH' | 'tr-TR' | 'uk-UA' | 'vi-VN' | 'zh-CN' | 'zh-HK' | 'zh-TW'
export type PostalCodeLocale = 'any' | 'AT' | 'AU' | 'BE' | 'BG' | 'CA' | 'CH' | 'CZ' | 'DE' | 'DK' | 'DZ' | 'ES' | 'FI' | 'FR' | 'GB' | 'GR' | 'IL' | 'IN' | 'IS' | 'IT' | 'JP' | 'KE' | 'LI' | 'MX' | 'NL' | 'NO' | 'PL' | 'PT' | 'RO' | 'RU' | 'SA' | 'SE' | 'TW' | 'US' | 'ZA' | 'ZM';
export type MobilePhoneLocal = 'any' | 'ar-AE' | 'ar-DZ' | 'ar-EG' | 'ar-JO' | 'ar-KW' | 'ar-SA' | 'ar-SY' | 'ar-TN' | 'be-BY' | 'bg-BG' | 'cs-CZ' | 'de-DE' | 'da-DK' | 'el-GR' | 'en-AU' | 'en-GB' | 'en-HK' | 'en-IN' | 'en-KE' | 'en-NG' | 'en-NZ' | 'en-PK' | 'en-RW' | 'en-SG' | 'en-TZ' | 'en-UG' | 'en-US' | 'en-CA' | 'en-ZA' | 'en-ZM' | 'es-ES' | 'et-EE' | 'fa-IR' | 'fi-FI' | 'fo-FO' | 'fr-FR' | 'he-IL' | 'hu-HU' | 'id-ID' | 'it-IT' | 'ja-JP' | 'kk-KZ' | 'kl-GL' | 'lt-LT' | 'ms-MY' | 'nb-NO' | 'nn-NO' | 'pl-PL' | 'pt-PT' | 'ro-RO' | 'ru-RU' | 'sk-SK' | 'sr-RS' | 'sv-SE' | 'th-TH' | 'tr-TR' | 'uk-UA' | 'vi-VN' | 'zh-CN' | 'zh-HK' | 'zh-TW'
export type PostalCodeLocale = 'any' | 'AT' | 'AU' | 'BE' | 'BG' | 'CA' | 'CH' | 'CZ' | 'DE' | 'DK' | 'DZ' | 'EE' | 'ES' | 'FI' | 'FR' | 'GB' | 'GR' | 'HR' | 'HU' | 'IL' | 'IN' | 'IS' | 'IT' | 'JP' | 'KE' | 'LI' | 'LT' | 'LU' | 'LV' | 'MX' | 'NL' | 'NO' | 'PL' | 'PT' | 'RO' | 'RU' | 'SA' | 'SE' | 'SI' | 'TN' | 'TW' | 'US' | 'ZA' | 'ZM';
export type HashAlgorithm = 'md4' | 'md5' | 'sha1' | 'sha256'| 'sha384'| 'sha512'| 'ripemd128'| 'ripemd160'| 'tiger128'| 'tiger160'| 'tiger192'| 'crc32'| 'crc32b';

@@ -42,4 +42,6 @@

isIP(version?: IPVersion): this;
isIPRange(): this;
isISIN(): this;
isISO31661Alpha2(): this;
isISO31661Alpha3(): this;
isISO8601(): this;

@@ -57,3 +59,3 @@ isISRC(): this;

isMongoId(): this;
isMobilePhone(locale: MobilePhoneLocal, options?: ValidatorOptions.IsMobilePhoneOptions): this;
isMobilePhone(locale: MobilePhoneLocal | MobilePhoneLocal[], options?: ValidatorOptions.IsMobilePhoneOptions): this;
isMultibyte(): this;

@@ -77,3 +79,3 @@ isNumeric(): this;

not(): this;
exists(): this;
exists(options?: ValidatorOptions.ExistsOptions): this;
optional(options?: ValidatorOptions.OptionalOptions): this;

@@ -233,2 +235,14 @@ withMessage(message: CustomMessageBuilder): this;

}
/**
* defaults to
* {
* checkNull: false,
* checkFalsy: false
* }
*/
interface ExistsOptions {
checkNull?: boolean;
checkFalsy?: boolean;
}
}

@@ -5,3 +5,2 @@ const validator = require('validator');

const { isSanitizer, isValidator } = require('../utils/filters');
const persistValues = require('../utils/persist-values');

@@ -18,3 +17,2 @@ module.exports = (fields, locations, message) => {

req._validationErrors = (req._validationErrors || []).concat(errors);
persistValues(req, middleware._context);
next();

@@ -77,3 +75,10 @@ }, next);

middleware.exists = () => middleware.custom(existsValidator);
middleware.exists = (options = {}) => {
const validator = options.checkFalsy
? existsValidatorCheckFalsy
: (options.checkNull ? existsValidatorCheckNull : existsValidator);
return middleware.custom(validator);
};
middleware.isArray = () => middleware.custom(value => Array.isArray(value));

@@ -113,2 +118,10 @@ middleware.isString = () => middleware.custom(value => typeof value === 'string');

return value !== undefined;
}
function existsValidatorCheckNull(value) {
return value != null;
}
function existsValidatorCheckFalsy(value) {
return !!value;
}

2

check/one-of.js
const _ = require('lodash');
const persistValues = require('../utils/persist-values');
const runner = require('./runner');

@@ -33,3 +32,2 @@

contexts.forEach(context => persistValues(req, context));
next();

@@ -36,0 +34,0 @@ return results;

@@ -38,3 +38,3 @@ const toString = require('../utils/to-string');

function getActualResult(result) {
const promiseLike = !!result.then;
const promiseLike = result && !!result.then;
return Promise.resolve(result).then(result => {

@@ -41,0 +41,0 @@ return result === undefined && promiseLike ? true : result;

@@ -24,3 +24,3 @@ import { ValidationChain, ValidatorOptions, CustomValidator } from './check';

custom?: ValidatorSchemaOptions<CustomValidator>;
exists?: ValidatorSchemaOptions;
exists?: ValidatorSchemaOptions<ValidatorOptions.ExistsOptions>;
optional?: boolean | ValidatorOptions.OptionalOptions;

@@ -60,4 +60,6 @@

isIP?: ValidatorSchemaOptions;
isIPRange?: ValidatorSchemaOptions;
isISIN?: ValidatorSchemaOptions;
isISO31661Alpha2?: ValidatorSchemaOptions;
isISO31661Alpha3?: ValidatorSchemaOptions;
isISO8601?: ValidatorSchemaOptions;

@@ -64,0 +66,0 @@ isISRC?: ValidatorSchemaOptions;

@@ -15,3 +15,3 @@ # Contributing to express-validator

## Pull Requests
Do you ant to dedicate your time to help improve the codebase? Great! Then submitting a pull request is the best way to do this.
Do you want to dedicate your time to help improve the codebase? Great! Then submitting a pull request is the best way to do this.

@@ -18,0 +18,0 @@ In case you opened a issue, then fixing it yourself is the fastest way to get it done.

@@ -7,4 +7,5 @@ import * as express from 'express';

export interface MatchedDataOptions {
includeOptionals: boolean;
onlyValidData: boolean;
locations: Location[];
}

@@ -5,3 +5,3 @@ const _ = require('lodash');

module.exports = (req, options = {}) => {
const fieldExtractor = createFieldExtractor(req);
const fieldExtractor = createFieldExtractor(req, options);
const validityFilter = createValidityFilter(req, options);

@@ -19,4 +19,5 @@ const locationsFilter = createLocationFilter(options);

function createFieldExtractor(req) {
function createFieldExtractor(req, { includeOptionals }) {
return context => [].concat(selectFields(req, context, {
filterOptionals: includeOptionals !== true,
// By the time we get here, all sanitizers did run, so we don't want double sanitization.

@@ -23,0 +24,0 @@ sanitize: false

const validator = require('validator');
const { isSanitizer } = require('../utils/filters');
const persistValues = require('../utils/persist-values');
const selectFields = require('../utils/select-fields');

@@ -11,3 +11,3 @@ module.exports = (fields, locations) => {

const middleware = (req, res, next) => {
persistValues(req, { fields, locations, sanitizers });
selectFields(req, { fields, locations, sanitizers });
next();

@@ -14,0 +14,0 @@ };

@@ -9,4 +9,4 @@ {

],
"version": "5.2.0",
"homepage": "https://github.com/express-validator/express-validator",
"version": "5.3.0",
"homepage": "https://express-validator.github.io",
"license": "MIT",

@@ -20,6 +20,10 @@ "repository": {

"scripts": {
"docs:build": "npm --prefix ./website run build",
"docs:publish": "USE_SSH=true CURRENT_BRANCH=master npm --prefix ./website run publish-gh-pages",
"docs:start": "npm --prefix ./website start",
"docs:version": "npm --prefix ./website run version",
"test": "nyc mocha && tsc",
"lint": "eslint lib test check filter",
"travis-build": "npm test && npm run lint",
"report-coverage": "cat coverage/lcov.info | coveralls"
"report-coverage": "cat coverage/lcov.info | coveralls",
"version": "npm run docs:version -- $npm_package_version && git add -A website"
},

@@ -31,3 +35,3 @@ "engines": {

"lodash": "^4.17.10",
"validator": "^10.1.0"
"validator": "^10.4.0"
},

@@ -38,2 +42,3 @@ "devDependencies": {

"coveralls": "^3.0.0",
"docusaurus": "^1.3.0",
"eslint": "^4.19.1",

@@ -40,0 +45,0 @@ "mocha": "^5.1.1",

@@ -13,15 +13,3 @@ # express-validator

- [Installation](#installation)
- [Usage](#usage)
- Features
- [Wildcards (`*`)](#wildcards-)
- [Dynamic messages](#dynamic-messages)
- [Schema validation](#schema-validation)
- [Whole body validation](#whole-body-validation)
- API
- [`check` API](#check-api)
- [`filter` API](#filter-api)
- [Sanitization Chain API](#sanitization-chain-api)
- [Validation Chain API](#validation-chain-api)
- [Validation Result API](#validation-result-api)
- [Legacy API](#legacy-api)
- [Documentation](#documentation)
- [Changelog](#changelog)

@@ -42,695 +30,5 @@ - [License](#license)

## Usage
> The version 3 style of doing validations is still available.
> Please check the [legacy API](#legacy-api) for the docs.
## Documentation
Please refer to the documentation website on https://express-validator.github.io.
```javascript
const { check, validationResult } = require('express-validator/check');
const { matchedData, sanitize } = require('express-validator/filter');
app.post('/user', [
check('username')
// Every validator method in the validator lib is available as a
// method in the check() APIs.
// You can customize per validator messages with .withMessage()
.isEmail().withMessage('must be an email')
// Every sanitizer method in the validator lib is available as well!
.trim()
.normalizeEmail()
// ...or throw your own errors using validators created with .custom()
.custom(value => {
return findUserByEmail(value).then(user => {
throw new Error('this email is already in use');
})
}),
// General error messages can be given as a 2nd argument in the check APIs
check('password', 'passwords must be at least 5 chars long and contain one number')
.isLength({ min: 5 })
.matches(/\d/),
// No special validation required? Just check if data exists:
check('addresses.*.street').exists(),
// Wildcards * are accepted!
check('addresses.*.postalCode').isPostalCode(),
// Sanitize the number of each address, making it arrive as an integer
sanitize('addresses.*.number').toInt()
], (req, res, next) => {
// Get the validation result whenever you want; see the Validation Result API for all options!
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.mapped() });
}
// matchedData returns only the subset of data validated by the middleware
const user = matchedData(req);
createUser(user).then(user => res.json(user));
});
```
---
## Wildcards (`*`)
To validate or sanitize nested object properties or an array of strings use wildcards (`*`).
```js
// Validate the postal code of each address, making sure the value is in postal code format
check('addresses.*.postalCode').isPostalCode(),
// Sanitize the number of each address, making it arrive as an integer
sanitize('addresses.*.number').toInt()
```
---
## Dynamic messages
You can build dynamic validation messages by providing functions anywhere a validation message is supported.
This is specially useful if you use a translation library to provide tailored messages:
```js
// check(field, withMessage) and .withMessage() work the same
check('something').isInt().withMessage((value, { req, location, path }) => {
return req.translate('validation.message.path', { value, location, path });
}),
check('somethingElse', (value, { req, location, path }) => {
return req.translate('validation.message.path', { value, location, path });
}),
// oneOf is special though - it only receives the req object for now
oneOf([ someValidation, anotherValidation ], ({ req }) => {
return req.translate('validation.multiple_failures');
});
```
---
## Schema Validation
Schemas are a special, object-based way of defining validations or sanitizations on requests.
At the root-level, you specify the field paths as the keys, and an object as values -- which define
the error messages, locations and validations/sanitizations.
Its syntaxs looks like this:
```js
const { checkSchema } = require('express-validator/check');
app.put('/user/:id/password', checkSchema({
id: {
// The location of the field, can be one or more of body, cookies, headers, params or query.
// If omitted, all request locations will be checked
in: ['params', 'query'],
errorMessage: 'ID is wrong',
isInt: true,
// Sanitizers can go here as well
toInt: true
},
myCustomField: {
// Custom validators
custom: {
options: (value, { req, location, path }) => {
return value + req.body.foo + location + path;
}
},
// and sanitizers
customSanitizer: {
options: (value, { req, location, path }) => {
let sanitizedValue;
if (req.body.foo && location && path) {
sanitizedValue = parseInt(value);
} else {
sanitizedValue = 0;
}
return sanitizedValue;
}
},
},
password: {
isLength: {
errorMessage: 'Password should be at least 7 chars long',
// Multiple options would be expressed as an array
options: { min: 7 }
}
},
firstName: {
isUpperCase: {
// To negate a validator
negated: true,
},
rtrim: {
// Options as an array
options: [[" ", "-"]],
},
},
// Wildcards/dots for nested fields work as well
'addresses.*.postalCode': {
optional: true,
isPostalCode: true
}
}), (req, res, next) => {
// handle the request as usual
})
```
---
## Whole Body Validation
Sometimes you need to validate requests whose body is a string, an array, or even a number!
That's why you can omit the field to validate and check `req.body` directly:
```js
const { body } = require('express-validator/check');
app.post('/recover-password', body().isEmail(), (req, res) => {
// Assume the validity was already checked
User.recoverPassword(req.body).then(() => {
res.send('Password recovered!');
});
});
```
---
## `check` API
These methods are all available via `require('express-validator/check')`.
### `check([field, message])`
- `field` *(optional)*: a string or an array of strings of field names to validate against.
- `message` *(optional)*: an error message to use when failed validators don't specify a message. Defaults to `Invalid value`; see also [Dynamic Messages](#dynamic-messages).
> *Returns:* a [Validation Chain](#validation-chain-api)
Creates a validation chain for one or more fields. They may be located in any of the following request objects:
- `req.body`
- `req.cookies`
- `req.headers`
- `req.params`
- `req.query`
If any of the fields are present in more than one location, then all instances of that field value must pass the validation.
**Note:** If `fields` is omitted, then the whole request location will be validated.
This is only useful for `req.body`, though; see [Whole Body Validation](#whole-body-validation) for examples.
The validators will always be executed serially for the same field.
This means that if the chain targets more than one field, those will run in parallel, but each of their validators are serial.
### `body([fields, message])`
Same as `check([fields, message])`, but only checking `req.body`.
### `cookie([fields, message])`
Same as `check([fields, message])`, but only checking `req.cookies`.
### `header([fields, message])`
Same as `check([fields, message])`, but only checking `req.headers`.
### `param([fields, message])`
Same as `check([fields, message])`, but only checking `req.params`.
### `query([fields, message])`
Same as `check([fields, message])`, but only checking `req.query`.
### `checkSchema(schema)`
- `schema`: the schema to validate. Must comply with the format described in [Schema Validation](#schema-validation).
> *Returns:* an array of validation chains
### `oneOf(validationChains[, message])`
- `validationChains`: an array of [validation chains](#validation-chain-api) created with `check()` or any of its variations,
or an array of arrays containing validation chains.
- `message` *(optional)*: an error message to use when all chains failed. Defaults to `Invalid value(s)`; see also [Dynamic Messages](#dynamic-messages).
> *Returns:* a middleware instance
Creates a middleware instance that will ensure at least one of the given chains passes the validation.
If none of the given chains passes, an error will be pushed to the `_error` pseudo-field,
using the given `message`, and the errors of each chain will be made available under a key `nestedErrors`.
Example:
```js
const { check, oneOf, validationResult } = require('express-validator/check');
app.post('/start-freelancing', oneOf([
check('programming_language').isIn(['javascript', 'java', 'php']),
check('design_tools').isIn(['photoshop', 'gimp'])
]), (req, res, next) => {
try {
validationResult(req).throw();
// yay! we're good to start selling our skilled services :)))
res.json(...);
} catch (err) {
// Oh noes. This user doesn't have enough skills for this...
res.status(422).json(...);
}
});
```
If an item of the array is an array containing validation chains, then all of those must pass in order for this
group be considered valid:
```js
// This protected route must be accessed either by passing both username + password,
// or by passing an access token
app.post('/protected/route', oneOf([
[
check('username').exists(),
check('password').exists()
],
check('access_token').exists()
]), someRouteHandler);
```
The execution of those validation chains are made in parallel,
while the execution within a chain still respects the rule defined in the [`check()` function](#checkfield-message).
### `validationResult(req)`
- `req`: the express request object.
> *Returns:* a [validation result](#validation-result-api) object
Extracts the validation errors from a request and makes it available in the form of a validation result object.
### `buildCheckFunction(locations)`
- `locations`: an array of request locations to gather data from.
May include any of `body`, `cookies`, `headers`, `params` or `query`.
> *Returns:* a variant of [`check()`](#checkfield-message) checking the given request locations.
Creates a variant of [`check()`](#checkfield-message) that checks the given request locations.
```js
const { buildCheckFunction } = require('express-validator/check');
const checkBodyAndQuery = buildCheckFunction(['body', 'query']);
app.put('/update-product', [
// id must be either in req.body or req.query, and must be an UUID
checkBodyAndQuery('id').isUUID()
], productUpdateHandler)
```
---
## `filter` API
These methods are all available via `require('express-validator/filter')`.
### `matchedData(req[, options])`
- `req`: the express request object.
- `options` *(optional)*: an object which accepts the following options:
- `onlyValidData`: if set to `false`, the returned value includes data from fields
that didn't pass their validations. Defaults to `true`.
- `locations`: an array of locations to extract the data from. The acceptable values include
`body`, `cookies`, `headers`, `params` and `query`. Defaults to `undefined`, which means all locations.
> *Returns:* an object of data validated by the `check` APIs.
Extracts data validated by the `check` APIs from the request and builds
an object with them. Nested paths and wildcards are properly handled as well.
```js
// Suppose the request looks like this:
// req.query = { from: '2017-01-12' }
// req.body = { to: '2017-31-12' }
app.post('/room-availability', check(['from', 'to']).isISO8601(), (req, res, next) => {
const queryData = matchedData(req, { locations: ['query'] });
const bodyData = matchedData(req, { locations: ['body'] });
const allData = matchedData(req);
console.log(queryData); // { from: '2017-01-12' }
console.log(bodyData); // { to: '2017-31-12' }
console.log(allData); // { from: '2017-01-12', to: '2017-31-12' }
});
```
### `sanitize(fields)`
- `field`: a string or an array of strings of field names to validate against.
> *Returns:* a [Sanitization Chain](#sanitization-chain-api)
Creates a sanitization chain for one or more fields. They may be located in any of the following request objects:
- `req.body`
- `req.cookies`
- `req.params`
- `req.query`
_* `req.headers` is **not** supported at the moment._
If any of the fields are present in more than one location, then all instances of that field value will be sanitized.
### `sanitizeBody(fields)`
Same as `sanitize(fields)`, but only sanitizing `req.body`.
### `sanitizeCookie(fields)`
Same as `sanitize(fields)`, but only sanitizing `req.cookies`.
### `sanitizeParam(fields)`
Same as `sanitize(fields)`, but only sanitizing `req.params`.
### `sanitizeQuery(fields)`
Same as `sanitize(fields)`, but only sanitizing `req.query`.
### `buildSanitizeFunction(locations)`
- `locations`: an array of request locations to gather data from.
May include any of `body`, `cookies`, `params` or `query`.
> *Returns:* a variant of [`sanitize()`](#sanitizefields) sanitizing the given request locations.
Creates a variant of [`sanitize()`](#sanitizefields) that sanitizes the given request locations.
```js
const { buildSanitizeFunction } = require('express-validator/filter');
const sanitizeBodyAndQuery = buildSanitizeFunction(['body', 'query']);
app.put('/update-product', [
// id being either in req.body or req.query will be converted to int
sanitizeBodyAndQuery('id').toInt()
], productUpdateHandler)
```
---
## Sanitization Chain API
The sanitization chain is a middleware, and it should be passed to an Express route handler.
When the middleware runs, it will modify each field in place, applying each of the sanitizers in the order they were specified:
```js
app.get('/', sanitizeBody('trimMe').trim(), (req, res, next) => {
// If req.body.trimMe was originally " something ",
// its sanitized value will be "something"
console.log(req.body.trimMe);
});
```
Any of the sanitization methods listed by [validator.js](https://github.com/chriso/validator.js) are made available in all sanitization chains created by express-validator, as long as we're supporting the most up-to-date validator version.
Additionally, the following methods are also available:
### `.customSanitizer(sanitizer)`
- `sanitizer(value, { req, location, path })`: the custom sanitizer function.
Receives the value of the field being sanitized, as well as the express request, the location and the field path.
> *Returns:* the current sanitization chain instance
Adds a custom sanitizer to the current sanitization chain. It must synchronously return the new value.
Example:
```js
app.get('/object/:id', sanitizeParam('id').customSanitizer((value, { req }) => {
return req.query.type === 'user' ? ObjectId(value) : Number(value);
}), objectHandler)
```
---
## Validation Chain API
Any of the validation and sanitization methods listed by [validator.js](https://github.com/chriso/validator.js) are made available in all validation chains created by express-validator, as long as we're supporting the most up-to-date validator version.
If you use any of the sanitizers together with validators, the validated value is the sanitized one.
**Note:** Chains are mutable. Every time you call one of its methods, you're adding more behavior to the same chain.
Keep this in mind and note that you probably want to use a factory function when reusing some chain base.
Additionally, the following methods are also available:
### `.custom(validator)`
- `validator(value, { req, location, path })`: the custom validator function.
Receives the value of the field being validated, as well as the express request, the location and the field path.
> *Returns:* the current validation chain instance
Adds a custom validator to the current validation chain.
The custom validator may return a promise to indicate an async validation task. In case it's rejected, the field is considered invalid.
The custom validator may also throw JavaScript exceptions (eg `throw new Error()`) and return falsy values to indicate the field is invalid.
Example:
```js
app.post('/create-user', [
 check('password').exists(),
 check('passwordConfirmation', 'passwordConfirmation field must have the same value as the password field')
.exists()
.custom((value, { req }) => value === req.body.password)
], loginHandler);
```
### `.customSanitizer(sanitizer)`
Same as [`.customSanitizer` from the Sanitization Chain](#customsanitizersanitizer).
### `.exists()`
> *Returns:* the current validation chain instance
Adds a validator to check for the existence of the current fields in the request.
This means the value of the fields may not be `undefined`; any other values are acceptable.
### `.isArray()`
> *Returns:* the current validation chain instance
Adds a validator to check if a value is an array.
### `.isString()`
> *Returns:* the current validation chain instance
Adds a validator to check if a value is a string.
### `.not()`
> *Returns:* the current validation chain instance
Negates the result of the next validator.
```js
check('weekday').not().isIn(['sunday', 'saturday'])
```
### `.optional(options)`
- `options` *(optional)*: an object of options to customize the optionality behaviour. Please check it below.
> *Returns:* the current validation chain instance
Marks the current validation chain as optional.
This is useful to remove values that are not essential to your busines and that would cause validation failures in case they were not provided in the request.
By default, fields with `undefined` values will be ignored from the validation.
You can further customize this behavior by passing an object with the following options:
- `nullable`: if `true`, fields with `null` values will be considered optional
- `checkFalsy`: if `true`, fields with falsy values (eg `""`, `0`, `false`, `null`) will also be considered optional
### `.withMessage(message)`
- `message`: the error message to use for the previous validator
> *Returns:* the current validation chain instance
Sets the error message for the previous validator.
This will have precedence over errors thrown by a custom validator.
To build dynamic messages, see also [Dynamic Messages](#dynamic-messages).
---
## Validation Result API
This is an unified API for dealing with errors, both in legacy and check APIs.
Each error returned by `.array()` and `.mapped()` methods have the following format by default:
```js
{
"msg": "The error message",
"param": "param.name.with.index[0]",
"value": "param value",
// Location of the param that generated this error.
// It's either body, query, params, cookies or headers.
"location": "body",
// nestedErrors only exist when using the oneOf function
"nestedErrors": [{ ... }]
}
```
### `.isEmpty()`
> *Returns:* a boolean indicating whether this result object contains no errors at all.
### `.formatWith(formatter)`
- `formatter(error)`: the function to use to format when returning errors.
The `error` argument is an object in the format of `{ location, msg, param, value, nestedErrors }`, as described above.
> *Returns:* this validation result instance
```js
app.post('/create-user', yourValidationChains, (req, res, next) => {
const errorFormatter = ({ location, msg, param, value, nestedErrors }) => {
// Build your resulting errors however you want! String, object, whatever - it works!
return `${location}[${param}]: ${msg}`;
};
const result = validationResult(req).formatWith(errorFormatter);
if (!result.isEmpty()) {
// Response will contain something like
// { errors: [ "body[password]: must be at least 10 chars long" ] }
return res.json({ errors: result.array() });
}
// Handle your request as if no errors happened
});
```
### `.array([options])`
- `options` *(optional)*: an object of options. Defaults to `{ onlyFirstError: false }`
> *Returns:* an array of validation errors.
Gets all validation errors contained in this result object.
If the option `onlyFirstError` is set to `true`, then only the first
error for each field will be included.
### `.mapped()`
> *Returns:* an object where the keys are the field names, and the values are the validation errors
Gets the first validation error of each failed field in the form of an object.
### `.throw()`
If this result object has errors, then this method will throw an exception
decorated with the same validation result API.
```js
try {
validationResult(req).throw();
// Oh look at ma' success! All validations passed!
} catch (err) {
console.log(err.mapped()); // Oh noes!
}
```
### `.withDefaults(options)`
- `options` *(optional)*: an object of options. Defaults to `{ formatter: error => error }`
> *Returns:* a new [validationResult](#validationresultreq) function is returned, using the provided options
This is useful when you have a consistent set of options you would like to use for all validation results throughout your application.
Below is an example which sets a default error formatter:
```
const { validationResult } = require('express-validator/check');
const result = validationResult.withDefaults({
formatter: (error) => {
return {
myLocation: error.location,
};
}
});
module.exports = result;
```
---
## Legacy API
The "legacy API" is the same API used by version 3 and older releases of express-validator.
It's based around setting a global middleware in your express app and decorating the request object with new methods.
> This API **MUST NOT** be used by new apps, since it may not receive new updates and can even be removed in a future major version.
### Setup
You must mount the middleware in your app before you get access to the validation/sanitization methods:
```js
const expressValidator = require('express-validator');
app.use(expressValidator(middlewareOptions));
```
### Middleware options
- `errorFormatter (param, msg, value, location)`: a function that formats the error objects before returning them to your route handlers.
- `customValidators`: an object where you can specify custom validators.
The key will be the name of the validator, while the value is the validation function, receiving the value and any option.
- `customSanitizers`: an object where you can specify custom sanitizers.
The key will be the name of the sanitizer, while the value is the sanitization function, receiving the value and any option.
### Legacy Validation Chain
The Legacy Validation Chain instances provides further functionality than the one provided by the base [Validation Chain](#validation-chain-api) objects.
It also differs in that the legacy one is not a middleware *per se*.
Any custom validator specified in the middleware will be made available
in instances of this validation chain.
Additionally, the following validators are also available:
- `.notEmpty()`: alias of `.isLength({ min: 1 })`
- `.len()`: alias of `.isLength()`
### `req.check(field[, message])`
- `field`: the name of a single field to validate against.
- `message` *(optional)*: an error message to use when failed validators don't specify a message. Defaults to `Invalid value`.
> *Returns:* a [legacy validation chain](#legacy-validation-chain)
Creates a validation chain for one field. It may be located in any of the following request objects:
- `req.params`
- `req.query`
- `req.body`
- `req.headers`
- `req.cookies`
If it's present in more than one location, then only the first one (following the above order) will be validated against.
> This function is also aliased as `req.assert()` and `req.validate()`.
### `req.checkBody(field[, message])`
Same as `req.check(field[, message])`, but only checking `req.body`.
### `req.checkCookies(field[, message])`
Same as `req.check(field[, message])`, but only checking `req.cookies`.
### `req.checkHeaders(field[, message])`
Same as `req.check(field[, message])`, but only checking `req.headers`.
### `req.checkParams(field[, message])`
Same as `req.check(field[, message])`, but only checking `req.params`.
### `req.checkQuery(field[, message])`
Same as `req.check(field[, message])`, but only checking `req.query`.
### `req.sanitize(field)`
> *Returns:* a sanitizer chain
Creates a sanitizer chain that, when any of the sanitization methods is used, the return value is the sanitized value.
Also, the parameter is sanitized in-place; that is, in the below example,
`req.body.comment` will be updated to the sanitized value.
```js
const comment = req.sanitize('comment').trim();
console.log(comment === req.body.comment);
```
If the sanitized parameter is present in more than one location (eg `req.query.comment` and `req.body.comment`), the will all be sanitized.
> This function is also aliased as `req.filter()`.
### `req.sanitizeBody(field[, message])`
Same as `req.sanitize(field[, message])`, but only sanitizing `req.body`.
### `req.sanitizeCookies(field[, message])`
Same as `req.sanitize(field[, message])`, but only sanitizing `req.cookies`.
### `req.sanitizeHeaders(field[, message])`
Same as `req.sanitize(field[, message])`, but only sanitizing `req.headers`.
### `req.sanitizeParams(field[, message])`
Same as `req.sanitize(field[, message])`, but only sanitizing `req.params`.
### `req.sanitizeQuery(field[, message])`
Same as `req.sanitize(field[, message])`, but only sanitizing `req.query`.
### `req.getValidationResult()`
> *Returns:* a promise for a [Validation Result](#validation-result-api) object
Runs all validations and returns a validation result object for the errors gathered, for both sync and async validators.
### `req.asyncValidationErrors([mapped])`
- `mapped` *(optional)*: whether the result must be an object instead of an array. Defaults to `false`.
> *Returns:* a promise which will resolve in case all validators passed, or reject with an array of errors or an object of errors (in case `mapped` argument is `true`).
Runs all validations and returns the errors gathered for all of them.
### `req.validationErrors([mapped])`
- `mapped` *(optional)*: whether the result must be an object instead of an array. Defaults to `false`.
> *Returns:* `false` if no errors happened, an array of errors or an object of errors (in case `mapped` argument is `true`).
Runs all validations and returns the errors gathered *only* for the completed validators.
This probably means any async validator will not be completed by the time this method responds.
### Schema validation
All `req.check` methods can do schema validation. The schema syntax is the same as described in [Schema Validation](#schema-validation).
---
## Changelog

@@ -737,0 +35,0 @@

@@ -1,2 +0,3 @@

const { body, oneOf, validationResult } = require('./check');
const expressValidator = require('./');
const { body, checkSchema, oneOf, validationResult } = require('./check');
const { matchedData } = require('./filter');

@@ -7,21 +8,38 @@ const express = require('express');

const app = express();
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.text());
app.post('/*', [
// body('trim1').trim(),
oneOf([
body('trim1').trim(),
body('trim2').trim(),
])
], (req, res) => {
console.log(req.body, req.query);
const data = matchedData(req);
const result = validationResult(req);
// app.use([
// body('id')
// // .customSanitizer(value => {
// // console.log(value);
// // return value._id;
// // })
// .toInt(),
// ], (req, res) => {
// const data = matchedData(req, { onlyValidData: false });
// const result = validationResult(req);
res.json({
data,
errors: result.mapped()
// res.json({
// data,
// errors: result.array()
// });
// });
app.use(expressValidator());
app.use((req, res) => {
req.checkBody('id').custom(value => {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, 3000);
});
});
req.getValidationResult().then(result => {
res.json({
errors: result.mapped()
});
});
});
app.listen(3000);
app.listen(3001);
const _ = require('lodash');
const selectFields = require('./select-fields');
module.exports = (req, context) => {
selectFields(req, context).filter(instance => {
module.exports = (req, fieldInstances) => {
fieldInstances.filter(instance => {
const initialValue = _.get(req[instance.location], instance.path);
return initialValue !== instance.value;
}).forEach(instance => {
_.set(req[instance.location], instance.path, instance.value);
instance.path === ''
? _.set(req, instance.location, instance.value)
: _.set(req[instance.location], instance.path, instance.value);
});
};
const _ = require('lodash');
const formatParamOutput = require('./format-param-output');
const persistValues = require('./persist-values');
module.exports = (req, context, options = {}) => {
let allFields = [];
const optionalityFilter = createOptionalityFilter(context);
const optionalityFilter = options.filterOptionals == null || options.filterOptionals
? createOptionalityFilter(context)
: Boolean;
const sanitizerMapper = createSanitizerMapper(req, context, options);

@@ -28,2 +31,3 @@

persistValues(req, allFields);
return _.uniqWith(allFields, _.isEqual);

@@ -30,0 +34,0 @@ };

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc