Ashh
Ashh

Reputation: 46451

Hapi validation for req.user.id and payload id

I am having simple route in hapi

const handler = async(request, reply) => {
  const id = Helpers.extractUserId(request)
  const payload = request.payload
  if (payload.recipient !== id) {
    // my code....
  } else {
    return reply({ success: false, message: '_id and recipient id should not match' })
    //I want to return this from routeConfig itself
  }
}

const routeConfig = {
  method: 'POST',
  path: '/requestfriend',
  config: {
    auth:'jwt',
    validate: {
      payload: {
        recipient: Joi.string().required().error(new Error('recipient is required'))
      }
    },
    handler
  }
}

I put a condition for if (payload.recipient !== id) which mean logged in user's id and payload recipient's are same then it should throw the error...

Instead of doing this I want to put this condition in routeConfig itself... So is there any parameter which can be used here just like auth, validate, handler?

Upvotes: 0

Views: 1152

Answers (2)

metoikos
metoikos

Reputation: 1364

You can validate your payload with hapi route validation options This is the notation.

validate: {
    payload: async (value, options) => {
    }
}

Here is the explanation

a validation function using the signature async function(value, options) where:

value - the request.payload object containing the request query parameters.

options - options.

if a value is returned, the value is used as the new request.payload value and the original value is stored in request.orig.payload.

Otherwise, the payload is left unchanged. If an error is thrown, the error is handled according to failAction.

Here is the sample code according to your application, this is just a dump sample, but I hope you can understand the idea here. You can validate payload, query and params object individually in every request. Just pass Joi validator or a function to validate incoming data.

const routeConfig = {
    method: 'POST',
    path: '/requestfriend',
    config: {
        auth: 'jwt',
        validate: {
            payload: async (value, options) => {
                // extract recipient data from payload
                const {recipient} = value;
                // you can now validate your recipient
                const result = Joi.validate({recipient}, Joi.string().required().error(new Error('recipient is required')), {abortEarly: false});
                if(result.error) throw Boom.badRequest(result.error);
                // there is no request object here, you have to dig in options.context parameter
                // this is how it's look like
                // {
                //     context:
                //         {
                //             headers:
                //                 {
                //                     host: 'localhost:3009',
                //                     'user-agent': 'curl/7.54.0',
                //                     accept: '*/*',
                //                     'content-length': '13',
                //                     'content-type': 'application/x-www-form-urlencoded'
                //                 },
                //             params: {},
                //             query: {x: 'y'},
                //             auth:
                //                 {
                //                     isAuthenticated: false,
                //                     isAuthorized: false,
                //                     credentials: null,
                //                     artifacts: null,
                //                     strategy: null,
                //                     mode: null,
                //                     error: null
                //                 },
                //             app: {route: {}, request: {}}
                //         },
                //     abortEarly: false
                // }

                // let's say we got id parameters here
                const id = Helpers.extractUserId(options.context);
                if(id !== recipient) throw Boom.badRequest('_id and recipient id should not match')
            }
        },
        handler
    }
}

Upvotes: 0

Ernest Jones
Ernest Jones

Reputation: 584

Well, it depends on what you want to do… If you are trying to authenticate user based on id, I advise you to check the relevant part of the doc

Really easy to implement:

  • Define a validate function in your server.js
  • Add authentication option in your route config

If the validation function return false your endpoint will return a 401 error.

Upvotes: 1

Related Questions