arb / celebrate

A joi validation middleware for Express.
MIT License
1.34k stars 65 forks source link

Use joi or() across keys in headers and body #135

Closed menocomp closed 5 years ago

menocomp commented 5 years ago

My joi schema looks like this:

const schema = Joi.object().keys({
  req: Joi.object()
    .keys({
      headers: Joi.object().keys({
        key: Joi.string(),
        other: Joi.string(),
      }),
      body: Joi.object().keys({
        key: Joi.string(),
        other: Joi.string(),
      })
    }).or('headers.key', 'body.key'),
});

The issue I am having with celebrate is:

I can write this kind of validation in Joi as follows:

const req = {
  method: 'post',
  headers: { key: 'ish',other: '123' },
  body: { other: '123' }
}

const { error, value } = schema.validate({ req });

which is working correctly, How can I write this in celebrate?

arb commented 5 years ago

I'm not sure exactly how you'd do it, but you can use the full req object and Joi.ref(). See this test for an example.

I'd give you some code, but again, I'm not actually 100% sure how you'd do it, but you'd likely be able to do it with a mix of ref and using the full request object as the validation context. You might need to make two schemas as well to get this working.

Does that help you at all?

menocomp commented 5 years ago

Thanks for your reply. Unfortunately I could not get it working with celebrate. I get it running correctly with JOI only.

I checked the source code and I think the issue is in these lines.

The issue here is that breaking down the express req object into headers/params/query/cookies and do validations one by one is the problem here.

I can not find a simple way to implement this while using celebrate.

arb commented 5 years ago

I think a custom middleware using Joi directly would likely be your easiest path forward. Again, as celebrate was strongly influenced by hapi, I'm pretty confident the response to this kind of question would be "You shouldn't accept key in two parts of the request. Enforce that it always needs to be in the headers or part of the body"

menocomp commented 5 years ago

Thanks for your reply. I had to detach celebrate from my code base. I wrote my own middleware and I am using Joi directly now.