[Fixed] How do I convert data from a buffer into a buffer?

Issue

I am trying to write a unit test to verify my signature function that calculates the signature of incoming data from a webhook. The function is working as expected and calculating the signature correctly.
Signature code:

exports.checkSignature = (req) => {
  let signatureComputed = this.computeSignatue(req.rawBody);
  const signature = req.header('X-WC-Webhook-Signature');
  return signature === signatureComputed;
};

exports.computeSignatue = (body) => {
  return crypto.createHmac('SHA256', process.env.WEBHOOK_SECRET).update(body).digest('base64');
};

However, when I try to test the computeSignature function in jest, I need to pass the ‘rawBody’ which is the buffer of the request body as defined in my server.js file:

app.use(
  express.json({
    verify: (req, res, buf) => {
      console.log(buf);
      req.rawBody = buf;
    },
  })
);

When I log the body input that is given to computeSignature I get the following:

{"type":"Buffer","data":[123,34,105,100,34,58,53,48,57,51,44,34,112,97,114,101,110,116,95,105,100,34,58,48,44,34,115,116,97,116,117,115,34,58,34,112,114,111,99,101,115,115,105,110,103,34,44,34,99,117,114,114,101,110,99,121,34,58,34,71,66,80,34,44,34,118,101,114,115,105,111,110...]}

I believe this is the decimal representation of the incoming JSON object as a string. I need to take this decimal representation and turn it into a Buffer to give to my jest function:

 describe('Security checks', () => {
    it('should succeed signature checks', () => {
      const result = helper.computeSignatue(MY_BUFFER);
      expect(result).toEqual('SIGNATURE_HERE');
    });
    it('should fail signature checks', () => {
      const result = helper.checkSignature(payloadData.badRequest);
      expect(result).toEqual(false);
    });
  });

I think the main problem is that I can’t mock the express middleware shown above that makes use of the ‘verify’ function. If I could mock this I would be able to pass my JSON object through and retrieve the buffer that way.

Solution

Here’s relevant documentation that shows how to construct a Buffer from an Array representation of its bytes:
https://nodejs.org/docs/latest-v14.x/api/buffer.html#buffer_static_method_buffer_from_array

If you need to use the "real" data that you console.logged as a test input, this is the way to go. Or, you could load test JSONs from files, e.g. using fs.readFile or fs.readFileSync – if you don’t specify an encoding, you get a Buffer of the bytes in the file.

Leave a Reply

(*) Required, Your email will not be published