Code Monkey home page Code Monkey logo

express-validation's Introduction

Hey ๐Ÿ‘‹

I'm Andrew, a software developer, educator and director at airasoul.com, based in London, UK. We design and engineer, scalable web and mobile applications using technologies such as โšก Serverless, Node.js, React, AI and blockchain.

โšก Serverless all the things, ฮž decentralise some of them

Recent Blog Posts

Publications

Contact Me

You can reach me at [email protected].

https://www.linkedin.com/in/andrewkeig/

Stats

andrewkeig

Andrew's GitHub Stats

Andrew's GitHub Streak

express-validation's People

Contributors

amarsyla avatar andrewkeig avatar apoorvmalhotra avatar aymericbeaumet avatar bkolodiy avatar bowernite avatar cherry avatar dependabot[bot] avatar derpoho avatar fedoryakubovich avatar fega avatar gdw2 avatar holm avatar iheanyi avatar ozonep avatar papandreou avatar rakibansary avatar rbarbey avatar rentzsch avatar slapers avatar unixdev 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  avatar  avatar

express-validation's Issues

Custom error messages

I want to use Joi's validate method to be able to add my custom validation message, because this is not very user friendly:

{
  "status": 400,
  "statusText": "Bad Request",
  "errors": [
    {
      "field": "pass",
      "location": "body",
      "messages": [
        "\"pass\" is required"
      ],
      "types": [
        "any.required"
      ]
    }
  ]
}

but Joi's validate message has 3 parameters: (value, schema, customMessage).. how do I achieve this ? I need to somehow inject value inside ?

expresss validation to check id present in param and body are same

Hi,
I have a scenario where i need id present in param and body to be same.
This is the validation schema i'm using:

module.exports.post= {
  body: {
      id: Joi.string().valid(Joi.ref('$params.id')).required()
  }
};

and the test case:

describe('when the schema contains an invalid reference to the request object', function() {
    it('should return a 400 response', function(done) {
      supertest(app)
        .post('/context/1')
        .send({id: '1'})
        .end(function(err, res) {
          if(err) {
            return done(err);
          }
          done();
        });
    });
  });

Even though the id's present in params and body are same I'm getting this response.

{
  "status": 400,
  "statusText": "Bad Request",
  "errors": [
    {
      "field": "id",
      "location": "body",
      "messages": [
        "\"id\" must be one of [context:params.id]"
      ],
      "types": [
        "any.allowOnly"
      ]
    }
  ]
}

Can anyone please help me in understanding what i'm doing wrong?

option flatten behaves unreasonable

Hi:
when I wrote a middleware to handle the error, I passed a option 'flatten', then I got an unexpected result. I read the code, and maybe that is the problem.
The origin code:

 ValidationError.prototype.toJSON = function () {
    if (this.flatten) return flatten(map(this.errors, 'messages'));
    return {
      status: this.status,
      statusText: this.statusText,
      errors: this.errors
    };
  };

or mybe it should be:

ValidationError.prototype.toJSON = function toJSON() {
    return {
      status: this.status,
      statusText: this.statusText,
      errors: this.flatten ? flatten(map(this.errors, 'messages')) : this.errors
    };
  };

Not sure if it is a bug, waiting for ur answer, thx!

TypeScript custom validator

How I can an extend the validator with my validator functions? I do this:

interface Validator extends ExpressValidator.Validator {
    isArray: () => ExpressValidator.Validator;
}

export interface IBaseRequest extends ExpressValidator.RequestValidation, express.Request {
    checkBody: {
        (item: string | string[], message?: string): Validator,
        (schema: {}): Validator
    };
}

when create express app:

app.use(validator({
     customValidators: {
         isArray: (value: any) => {
                return Array.isArray(value);
         }
     }
}));

but I think it's not a right solution. Can you help me or say how I can do this right.

Response headers from error should be application/json

The response of the error given by express-validation is text/html; charset=utf-8 when it should be application/json; charset=utf-8. Because it is text/html responses given back are parsed as below:

{"status":400,"statusText":"Bad Request","errors":[{"field":"content-type","location":"headers","messages":["\"content-type\" must be one of [application/json;charset=UTF-8]"],"types":["any.allowOnly"]}]}

No Joi options API for i18n language config

As in lib/index.js at line:69

  var joiOptions = {
    context: context || request,
    allowUnknown: allowUnknown,
    abortEarly: false
    // , language: {...}
  };

May it configurable for the joiOptions which user could add other options like language for Joi?

I didn't find any approach or workaround to make it happen now, or did I miss anything?

Cookie validation

I wonder if there was a specific reason to omit the cookies validation? I'm currently facing the use-case where I need to do a preliminary check for a cookies before using its content.

Feature request: remove unknown fields

Until now, you have allowUnknown*, which make sure that keys not intended in the data are passed through or not.

This is a feature request:

Modify the options, such that keys not intended to be in the data are dropped. The idea comed from Paperwork:

Paperwork now silently removes unknown fields from the validated blob. This is done so you never pass unvalidated data to your code. For instance, if an attacker was to pass an extra id, you might end up using it to update the wrong object in your database.

I also pushed this idea for isvalid. There we use the following schema:

  • unknownBody with the possible values of 'allow', 'deny', 'remove'

Instad of allowUnknown*: false and allowUnknown*: true

The reason is the following: middleware frameworks such as Angular are sending a lot more framework specific data within the JSON, which I want to be removed.

AssertionError using Joi schema definition with express-validation from a different module

Context

  • node version: v9.4.0
  • joi version: 13.1.2
  • environment (node, browser): node
  • used with (hapi, standalone, ...): with express-validation
  • any other relevant information: N/A

What are you trying to achieve or the steps to reproduce ?

I'm trying to define my Joi schema in one module and include it in different modules (the base definition are meant to be shared in more modules to avoid code duplication). But seems like some definition works, other doesn't.

Module 1

import Joi from 'joi';

const working1 = Joi.string().alphanum().min(3).max(20).required();
const working2 = Joi.string().required().min(5);
const notWorking1 = Joi.number().default(0).min(0);

export default {
  working1,
  working2,
  notWorking1,
};

Module 2

import m from './module1';

export default {
  rule1: {
    body: {
      field1: r.working1,
      field2: r.working2,
    },
  },
};

Module 3

import m from './module1';

export default {
  rule2: {
    query: {
      field1: r.notWorking1,
    },
  },
};

Which result you had ?

Some validation schema are working well, while in other case I get a weird error (ex in module3). Something like this:

AssertionError [ERR_ASSERTION]: Invalid schema content: (rule2)
{"generatedMessage":false,"name":"AssertionError [ERR_ASSERTION]","code":"ERR_ASSERTION","actual":false,"expected":true,"operator":"==","path":"rule2"}

If I include the validation schema in the module3 file without importing it from the module1 it work as expected.

The schemas are included inside the ruotes using express-validation module.

import { Router } from 'express';
import validation from 'express-validation';
import v3 from './module3';
import v2 from './module2';

router.get('/x', validation(v2.rule1), (req, res, next) => ... ); // working
router.get('/y', validation(v3.rule2), (req, res, next) => ... ); // not working

What did you expect ?

I expect that it works in any case. Am I missing something?

Only getting single generic validation error message

My express routes are working and all the validation rules I've defined are being enforced, however on validation failure I am not getting any detailed errors - regardless of which rule fail, I get a 400 (as expected) but the response is always generic.

{
  "error": "validation error"
}

bad request body

Hey! This is more of a question than an issue.

When a request is bad, does the content of the response body reflect why the request was bad?

failed `npm install` with npm@3

NOTE: npm versions 1 and 2 will automatically install peerDependencies if they are not explicitly depended upon higher in the dependency tree. In the next major version of npm (npm@3), this will no longer be the case. You will receive a warning that the peerDependency is not installed instead.

Possible to enable strict checking globally?

Hi there, and thanks for a great middleware! Really, really useful.

One question - I'm wondering if it's possible to enable strict checking of say, body or params as a default behaviour instead of enabling this on a per-use basis.

This doesn't seem to be the case via the docs.

Validation throws a 500 rather than 400

Hi, I've stripped out all other middleware and used the example in the README, express-validation has installed Joi as a dependency so version should be okay, but it is throwing a 500 on invalidate req object rather than the expected 400. Here is the test case;

`

 //app.js  
router.use(bodyParser.json());
router.post('/:version/:publisher/:id/:assetType', 
validate(storyValidator),
(req, res) => {

  const content = req.content;
  const assetsToQueuePromises = [];
  const assetsToRedisPromises = [];
  const storyIds = {topCardId:undefined, cardIds:[]};
  res.send(200);
   .....
 })

 //storyValidator
 const Joi = require('joi'); 
   module.exports = {
   body: {
     email: Joi.string().email().required(),
     password: Joi.string().regex(/[a-zA-Z0-9]{3,30}/).required()
   }
 };

 //test.js
  it.only('should validate a card correctly when all data is present',(done) => {
    request(app)
    .post('/v1/ft/765890/card')
    .send({
      email: "[email protected]",
      password: ""})
    .expect(400)  //actually throws 500
    .end( (err, res) => {
      console.log(err);
      done();
    })

   `

Thanks in advance - what am I doing wrong. Using 1.0.0

Call next with an error on validation failures instead of sending JSON

It would be great to provide an option that would cause the middleware to next an error instead of sending JSON. This would allow an error handler to be written that would support content negotiation for error messages. Furthermore, it would express-validation to be used in cases where a validation failure is not strictly the end of a routing chain.

I would be more than happy to author this change if you think this feature belongs in this package.

validation on param converter

Hi,

How I can use validation in a param converter?
I wanted to use Joi.objectId () to validate that this is a mongodb valid id

router.route('/:id')
  /** GET /api/users/:userId - Get user */
  .get(validate(paramValidation.get),userCtrl.get)

  /** PUT /api/users/:userId - Update user */
  .put(validate(paramValidation.updateUser), userCtrl.update)

  /** DELETE /api/users/:userId - Delete user */
  .delete(validate(paramValidation.deleteUser), userCtrl.remove);

/** Load user when API with userId route parameter is hit */
router.param('id', userCtrl.load);

Thanks and regards

required() timeout error

Hey, not sure if my problem goes here or to https://github.com/hapijs/joi/, so let me explain, I have this validation:

{
  body: {
    firstname: Joi.string().required(),
    lastname: Joi.string().required(),
  }
}

and if I send a request with {"firstname":"bob","lastname":""}, I get the corresponding error since both are required.

But if I send the request with {"firstname":"bob"}, it does not generate an error, in fact it does not generate anything at all, and my request keeps waiting until timeout, only works if I explicitly send the lastname parameter (although empty).

I think that the validator should not assume that some values are sent, but instead generate errors for everything, no matter how many.

Well, thanks in advance and forgive me if I am doing something wrong or this problem belongs to Joi or somewhere else

Edit: Sorry, I accidentally closed the issue in order to edit my question.
Edit2: I found that I could change .required() for .min(1) for strings but don't know how to handle other types

Validating array body

Hi,

Not sure if this is a bug or not, but let me explain what I want to do and the results I see.

I want to validate a that the body of a POST is a JSON array of objects. I have a schema like this:

{
  body: Joi.array().items(Joi.object()).required()
}

If I send in body data that is an array, [{id:1}] then I get this error:

Error: \"context\" must be an object\n
    at Object.internals.checkOptions (/Users/23046666/Projects/so-domain/node_modules/joi/lib/any.js:38:15)\n
    at [object Object].internals.Any.applyFunctionToChildren.internals.Any._validateWithOptions (/Users/23046666/Projects/so-domain/node_modules/joi/lib/any.js:628:19)\n
    at [object Object].root.validate (/Users/23046666/Projects/so-domain/node_modules/joi/lib/index.js:104:23)\n
    at validate (/Users/23046666/Projects/so-domain/node_modules/express-validation/lib/index.js:77:7)\n
    at /Users/23046666/Projects/so-domain/node_modules/express-validation/lib/index.js:42:24\n
    at Array.forEach (native)\n
    at /Users/23046666/Projects/so-domain/node_modules/express-validation/lib/index.js:39:55

It seems that Joi requires the body to be an objext. And to verify, If I send body data that is an object, {id:1}, then I don't see the error. (But instead the validation catches it, as it should.)

Looking at the code it seems that the body is set to the context attribute in options sent to Joi, and Joi checks that it is a Joi.object(). This was not the case in Joi 8.1.0, but has changed somewhere to Joi 8.4.2.

Do we really need to set the context attribute to the payload? Or is there any other way to keep it possible to validate arrays in the body?

Thanks!

Schema validation using express-validation

Is it possible to check conditional parameter using express-validation?
I want my JSON to have a value in either a or b or both.If both of them doesn't have any value it should return 400 bad request.So I tried with 'OR' condition as given below.

Scenario:
payload= {
body : {
'properties' : Joi.object().keys({
'a':Joi.any(),
'b':Joi.any()
}).or('properties.a','properties.b')
}
};

This is the payload i'm giving as input:

{
"properties": {
"a":"2123",
"b":"1234"
}
}

Even though i'm providing both a and b i'm getting this response:

{
"status": 400,
"statusText": "Bad Request",
"errors": [
{
"field": "properties",
"location": "body",
"messages": [
""value" must contain at least one of [properties.a, properties.b]"
],
"types": [
"object.missing"
]
}
]
}

Can you help me with this situation?

MIT license okay?

Hi Andrew. I specified the "MIT" license in the package.json. I hope that's okay! ( I thought it would do a PR instead of just committing it when editing it through the github UI, but it didn't.)

Give a name to your middleware help me Unit Test my routes

Hi,

Testing my routes, I list all middleware for my routes, and I want to assert 'Validate' middleware is implemented.
Currently, as it has no given name, it returns me .
A simple change at line 32 in index.js
from : return function (req, res, next)
to : return function Validate (req, res, next)
Now gives me "Validate" as handler name, and it's ok.

Do you think it's ok to add this change in next version ?
Thanks a lot

Change default status code at declaration

I appreciate status code and status text can be customized by a per-validation basis, but what about changing globally at requre level?

As

var validation = require('express-validation')({ status: 422, statusText: 'Unprocessable Entity' });

Problems

  1. I don't understand who is validation.login passed at validate(validation.login) - if is the Joi Schema immediately below, or anything else.
  2. You've to Change app.use(express.bodyParser()), because it returns -> Error: Most middleware (like bodyParser) is no longer bundled with Express and must be installed separately.

Breaking changes in 0.4.4

Hi there,

It seems like in 0.4.3 to 0.4.4 req.query is manipulated now so that it is parsed, so anywhere that we have code that, after validation, might JSON.parse(req.query.xyz) it will already be an object. This can be dealt with defensively, but not sure I want my validation to manipulate my request and if I do, should probably go under a major version bump?

_assignIn doesn't cope with all Joi mutations

assignIn(request, value); // joi responses are parsed into JSON

I have a validation that strips fields under certain conditions. This doesn't work with express-validation because it copies keys from the Joi result to the result body, but keys that are omitted aren't removed.

Rather than place the responsibility of mutating the result in two places - Joi and express-validation, it works better if you just take the output of Joi and replace the contents of that key in the request.

Add option allowEmptyBody: Boolean

It could be useful when you need a patch request that shouldn't be empty, but none of the parameters are required (only you update whatever you need)

How to remove slash '\' character out of error messages

Hi all,

I'm using joi to validate my apis request. All things is good except the error message return the field name with slash '' character.

{
  "message": "validation error",
  "error": {
    "status": 400,
    "statusText": "Bad Request",
    "errors": [
      {
        "field": "email",
        "location": "body",
        "messages": [
          "\"email\" must be a valid email"
        ],
        "types": [
          "string.email"
        ]
      }
    ]
  }
}

Do we have any option to remove it ?
Thanks,

Allow to pass global joi options like: { presence: 'required' }

Please make it available to set the default for joi schema as { presence: 'required' },
I don't like setting .required() for each rule that I add, it's easier for me to specify .optional() when needed.
Also - allow to change this 'presence' setting per request (and not only global defaults).

If you agree with this I would be happy to send a PR.

Upgrade to Joi 10

Hi,

I've seen you've already bumped joi in the master branch, but you haven't released it. The issue here is more to ask you to release a version that requires a peer dependency of joi@^10.0.0 :). Let me explain why:

I'm using express-validation (with joi) and vanilla joi somewhere else in my project. I use joi 10 and since the latest published version requires a peer dependency of joi@^9.0.4, I get the warning on install.

Well, it's usually no big deal: but I'm currently shrinkwraping my projects to lock dependencies versions. It appears you can't if a peer dependency is missing -_-.

Since I use Joi 10 somewhere else in the project and that I can't have two versions of the same package in my package.json, I'm currently blocked for my shrinkwrap :/.

Can I expect a release in a near future?

Cheers,
tex0l.

Upgrade to Joi ^9.0.4

Express-validation is requiring a version of Joi ^8.0.5. But the most recent release of Joi is 9.0.4. It would be great if this was updated so I can use the latest version of Joi.

TypeError: Cannot read property 'length' of undefined - when using .error()

When trying to set a custom error message as per Joi API reference, for example:
Joi.string().error(new Error('expected a string, actually'))
then express-validation throws
TypeError: Cannot read property 'length' of undefined in index.js line 76
because .error(new Error('message')) produces an Error instance without .details or other decorations of the ValidationError so errors.details.length cannot be accessed directly as errors.details is undefined.

Should another route be chosen to allow for custom error messages (especially important for regexes) or should the condition be improved to distinguish between ValidationErrors and generic Errors?

No Way to Use Dependencies

Not sure if this is an issue or maybe just a new feature but in Joi you can do something like this:

const schema = Joi.object().keys({
a: Joi.any(),
b: Joi.any()
}).xor('a', 'b');

where then it is saying you can have either a or b but not both and that ends up in a attribute called "dependencies" in the Joi Object. There seems to be no way to get that "xor" section into the Joi schema within express-validation

Unable to validate arrays without context.

So, this is more of a feature of Joi that is buggy but currently we can't do this with Express-Validation in order to use a reference value on an array. I think I know of a workaround/fix for this and that would be passing in an allowContext input at the validaton function line 55 and then also making the default context equal to false in these lines of code. If allowContext === true, the request would get passed in as the context variable on line 61. Let me know your thoughts on this. Thanks.

var Joi = require("joi");

var schema = {
  a: Joi.array().items(Joi.number().valid([1, 2, 3, 10, 11])),
  b: Joi.array().items(Joi.number().valid(Joi.ref('$a'))),
  c: Joi.any()
}

var example1 = {
  a: [1, 2, 3],
  b: [1, 2],
  c: 1
};

// Without context
Joi.validate(example1, schema, function(err, value) {
  if(err) {
    console.log("Error!");
    console.log(err);
    console.log(JSON.stringify(err.details)); 
  }

  console.log(value);
}); // Doesn't work properly, will throw errors.

// With context
Joi.validate(example1, schema, {context: example1}, function(err, value) {
  if(err) {
    console.log("Error!");
    console.log(err);
    console.log(JSON.stringify(err.details)); 
  }

  console.log(value);
}); // Works properly

Content-Type is set to text/html

It could be my issue, but I have no idea what am I doing wrong.

How could I change Content-Type to application/json?

router:

router.get('/:id', [validate(validation.module.get)], controller.get);

validator:

var Joi = require('joi');

module.exports = {
    params: {
        id: Joi.number().required()
    }
};

Test code:

request(app)
    .get('/module/test')
    .set('Accept', 'application/json')
    .expect(400)
    .expect('Content-Type', /application\/json/)
    .end(function(err, res) {
        done();
    });

Error message:

Error: expected "Content-Type" matching /application\/json/, got "text/html; charset=utf-8"

Middleware send text/html instead of application/json

What I get from validation is this:

< HTTP/1.1 100 Continue
< HTTP/1.1 400 Bad Request
< X-Powered-By: Express
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 299
< Date: Wed, 27 Jul 2016 10:19:37 GMT
< Connection: keep-alive
* HTTP error before end of send, stop sending
< 
{&quot;status&quot;:400,&quot;statusText&quot;:&quot;Bad Request&quot;,&quot;errors&quot;:[{&quot;field&quot;:&quot;page&quot;,&quot;location&quot;:&quot;body&quot;,&quot;messages&quot;:[&quot;\&quot;page\&quot; must be larger than or equal to 1&quot;],&quot;types&quot;:[&quot;number.min&quot;]}]}
* Closing connection 0

How to change content-type and prevent html escaping?

Test Timeout - jasmine.DEFAULT_TIMEOUT_INTERVAL

I'm using your middleware with joi. When I added your middleware validation function the tests started to throw a timeout exception (see message bellow).

It sounds weird because I'm testing only Nodejs code, not in a browser.

The validation rule is:

body: {
    to: Joi.string().required()
  }

The error message:

 FAIL  src/api/chat/index.test.js (100.512s)
  โ— POST /chat/send 201 (user)

    Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
      
      at ontimeout (timers.js:365:14)
      at tryOnTimeout (timers.js:237:5)
      at Timer.listOnTimeout (timers.js:207:5)

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.