Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/real-badgers-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fix receiving webhook payloads as x-www-form-urlencoded JSON
Comment thread
sampaiodiego marked this conversation as resolved.
Outdated
10 changes: 6 additions & 4 deletions apps/meteor/app/integrations/server/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,19 +319,21 @@ Api.router.use((req, res, next) => {
return next();
}

const payloadKeys = Object.keys(req.body);
if (payloadKeys.length !== 1) {
// make sure body has only one key and it is 'payload'
if (!req.body || typeof req.body !== 'object' || !('payload' in req.body) || Object.keys(req.body).length !== 1) {
return next();
}

try {
// need to compose the full payload in this weird way because body-parser thought it was a form
req.bodyParams = JSON.parse(payloadKeys[0] + req.body[payloadKeys[0]]);
req.bodyParams = JSON.parse(req.body.payload);

return next();
} catch (e) {
res.writeHead(400);
res.end(JSON.stringify({ success: false, error: e.message }));
}

return next();
});

Api.addRoute(
Expand Down
25 changes: 25 additions & 0 deletions apps/meteor/tests/end-to-end/api/incoming-integrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,31 @@ describe('[Incoming Integrations]', () => {
expect(!!(res.body.messages as IMessage[]).find((m) => m.msg === successfulMesssage)).to.be.true;
});
});

it('should send a message if the payload is a application/x-www-form-urlencoded JSON', async () => {
const payload = { msg: `Message as x-www-form-urlencoded JSON sent successfully at #${Date.now()}` };

await request
.post(`/hooks/${integration._id}/${integration.token}`)
.set('Content-Type', 'application/x-www-form-urlencoded')
.send(`payload=${JSON.stringify(payload)}`)
.expect(200)
.expect(async () => {
return request
.get(api('channels.messages'))
.set(credentials)
.query({
roomId: 'GENERAL',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('messages').and.to.be.an('array');
expect(!!(res.body.messages as IMessage[]).find((m) => m.msg === payload.msg)).to.be.true;
});
});
});
});

describe('[/integrations.history]', () => {
Expand Down