Skip to content

Commit

Permalink
fix: fix validateExpressRequest issue (#665)
Browse files Browse the repository at this point in the history
  • Loading branch information
shwetha-manvinkurke authored Mar 15, 2021
1 parent 65a59af commit 671c7ac
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 3 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ const client = require('twilio')(accountSid, authToken);
client.logLevel = 'debug';
```

## Using webhook validation
See [example](examples/express.js) for a code sample for incoming Twilio request validation

## Handling Exceptions

For an example on how to handle exceptions in this helper library, please see the [Twilio documentation](https://www.twilio.com/docs/libraries/node/usage-guide#exceptions).
Expand Down
32 changes: 32 additions & 0 deletions examples/express.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const twilio = require('twilio');
const bodyParser = require('body-parser');
const MessagingResponse = require('twilio').twiml.MessagingResponse;

const express = require('express')
const app = express()
const port = 3000

app.use(bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf
}
}))

app.get('/', (req, res) => {
res.send('Hello World!')
})

app.post('/message', twilio.webhook(), (req, res) => {
// Twilio Messaging URL - receives incoming messages from Twilio
const response = new MessagingResponse();

response.message(`Your text to me was ${req.body.Body}.
Webhooks are neat :)`);

res.set('Content-Type', 'text/xml');
res.send(response.toString());
});

app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
2 changes: 1 addition & 1 deletion lib/webhooks/webhooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ function validateExpressRequest(request, authToken, opts) {
authToken,
request.header('X-Twilio-Signature'),
webhookUrl,
request.body || {}
request.rawBody || '{}'
);
} else {
return validateRequest(
Expand Down
15 changes: 13 additions & 2 deletions spec/validation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ const bodySignature = '0a1ff7634d9ab3b95db5c9a2dfe9416e41502b283a80c7cf19632632f
const requestUrlWithHash = requestUrl + '&bodySHA256=' + bodySignature;
const requestUrlWithHashSignature = 'a9nBmqA0ju/hNViExpshrM61xv4=';

const requestUrlWithHashSignatureEmptyBody = 'Ldidvp12m26NI7eqEvxnEpkd9Hc=';
const bodySignatureEmpty = '44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a';
const requestUrlWithHashEmpty = requestUrl + '&bodySHA256=' + bodySignatureEmpty;

describe('Request validation', () => {
it('should succeed with the correct signature', () => {
const isValid = validateRequest(token, defaultSignature, requestUrl, defaultParams);
Expand Down Expand Up @@ -55,6 +59,12 @@ describe('Request validation', () => {
expect(isValid).toBeTruthy();
});

it('should validate request body when empty', () => {
const isValid = validateRequestWithBody(token, requestUrlWithHashSignatureEmptyBody, requestUrlWithHashEmpty, '{}');

expect(isValid).toBeTruthy();
});

it('should validate request body with only sha param', () => {
const sig = bodySignature.replace('+', '%2B').replace('=', '%3D');
const shortUrl = 'https://mycompany.com/myapp.php?bodySHA256=' + sig;
Expand Down Expand Up @@ -265,6 +275,7 @@ describe('Request validation middleware', () => {
}),
}));

request.rawBody = body;
middleware(request, response, () => {
done();
});
Expand Down Expand Up @@ -296,8 +307,8 @@ describe('Request validation middleware', () => {
const newUrl = fullUrl.pathname + fullUrl.search + '&somethingUnexpected=true';
const request = httpMocks.createRequest(Object.assign({},
defaultRequestWithoutTwilioSignature, {
originalUrl: newUrl,
}));
originalUrl: newUrl,
}));

middleware(request, response, () => {
expect(true).toBeFalsy();
Expand Down

0 comments on commit 671c7ac

Please sign in to comment.