1

How could I create a proper signature from POST body in express.js application?

I can't figure out what I should send instead of payload in official documentations. I tried to pass req.body in different way, but without any success. There are bunch of middlewares (especially body-parser-xml) before appropriate controller.

function ComputeHash (secret, payload)

{

  var crypto = require('crypto');

  var hmac = crypto.createHmac('sha256', secret);

  hmac.write(payload);

  hmac.end();

  return hmac.read().toString('base64');
}
zardosht
  • 3,014
  • 2
  • 24
  • 32

3 Answers3

0

You need only the body (payload), nothing else. I wouldn't try to parse the xml. Not a js guy but the bellow link I think describes the ways to get the body in nodejs How to process POST data in Node.js?

IvanD
  • 773
  • 5
  • 7
0

You want the raw POST body. Express usually delivers streams, so one technique would be to add the body stream's parts into the hash piece by piece.

It looks like there's a body-parser#raw that you can set up as Express middleware that will give you the body as a single chunk of content.

Note that one of its options is the max body length. If you are including the envelope's documents in the Connect notification, the size can easily reach 20MB or more.

...and that's why it is not recommended that you include envelopes' documents in the webhook (Connect) notifications. Instead, use the notification as a trigger to then download the docs.

Also, I strongly recommend that you use a PaaS queuing system to queue the notification messages. See the blog post and code examples.

Larry K
  • 47,808
  • 15
  • 87
  • 140
0

I found a solution.

const rawBodySaver = function (req, res, buf, encoding) {
  if (buf && buf.length) {
    req.rawBody = buf.toString(encoding || 'utf8');
  }
}

router.post('/webhook', bodyParser.xml({
  limit: '2MB',    
  extended: true, 
  verify: rawBodySaver, 
  type: '*/*', 
  xmlParseOptions: {
    normalize: false,     // Trim whitespace inside text nodes
    normalizeTags: true, // Transform tags to lowercase
    explicitArray: false // Only put nodes in array if >1
  },
 }), async function(req, res, next) {
  try {
    return DocsController.webhook(req, res);
  } catch (e) {
    console.log(e);
    return res.status(500).send('Internal error');
  }
});