regression: parse urlencoded body as string when there is no specific key(payload) (#35823)

pull/35746/head^2
Marcos Spessatto Defendi 9 months ago committed by GitHub
parent fe5f8a2cf3
commit 72fbdac4f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      apps/meteor/app/api/server/router.ts
  2. 19
      apps/meteor/app/integrations/server/api/api.js
  3. 75
      apps/meteor/tests/end-to-end/api/incoming-integrations.ts

@ -166,7 +166,7 @@ export class Router<
// eslint-disable-next-line no-empty
} catch {}
return { ...overrideBodyParams };
return {};
}
private parseQueryParams(request: HonoRequest) {

@ -94,7 +94,7 @@ async function executeIntegrationRest() {
}
const content_raw = Buffer.concat(buffers).toString('utf8');
const protocol = `${this.request.headers.get('x-forwarded-proto')}:` || 'http:';
const url = new URL(this.request.url, `${protocol}//${this.request.headers.host}`);
const url = new URL(this.request.url, `${protocol}//${this.request.headers.get('host')}`);
const request = {
url: {
@ -325,13 +325,22 @@ const middleware = async (c, next) => {
}
try {
const body = Object.fromEntries(new URLSearchParams(await req.raw.clone().text()));
if (!body || typeof body !== 'object' || !('payload' in body) || Object.keys(body).length !== 1) {
const content = await req.raw.clone().text();
const body = Object.fromEntries(new URLSearchParams(content));
if (!body || typeof body !== 'object' || Object.keys(body).length !== 1) {
return next();
}
// need to compose the full payload in this weird way because body-parser thought it was a form
c.set('bodyParams-override', JSON.parse(body.payload));
if (body.payload) {
// need to compose the full payload in this weird way because body-parser thought it was a form
c.set('bodyParams-override', JSON.parse(body.payload));
return next();
}
incomingLogger.debug({
msg: 'Body received as application/x-www-form-urlencoded without the "payload" key, parsed as string',
content,
});
c.set('bodyParams-override', JSON.parse(content));
} catch (e) {
c.body(JSON.stringify({ success: false, error: e.message }), 400);
}

@ -398,6 +398,81 @@ describe('[Incoming Integrations]', () => {
await removeIntegration(withScript._id, 'incoming');
});
it('should send a message if the payload is a application/x-www-form-urlencoded JSON(when not set, default one) but theres no "payload" key, its just a string, the integration has a valid script', async () => {
const payload = { test: 'test' };
let withScript: IIntegration | undefined;
await updatePermission('manage-incoming-integrations', ['admin']);
await request
.post(api('integrations.create'))
.set(credentials)
.send({
type: 'webhook-incoming',
name: 'Incoming test with script and default content-type',
enabled: true,
alias: 'test',
username: 'rocket.cat',
scriptEnabled: true,
overrideDestinationChannelEnabled: false,
channel: '#general',
script:
'const buildMessage = (obj) => {\n' +
' \n' +
' const template = `[#VALUE](${ obj.test })`;\n' +
' \n' +
' return {\n' +
' text: template\n' +
' };\n' +
' };\n' +
' \n' +
' class Script {\n' +
' process_incoming_request({ request }) {\n' +
' msg = buildMessage(request.content);\n' +
' \n' +
' return {\n' +
' content:{\n' +
' text: msg.text\n' +
' }\n' +
' };\n' +
' }\n' +
' }\n' +
' \n',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('integration').and.to.be.an('object');
withScript = res.body.integration;
});
if (!withScript) {
throw new Error('Integration not created');
}
await request
.post(`/hooks/${withScript._id}/${withScript.token}`)
.send(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 === '[#VALUE](test)')).to.be.true;
});
});
await removeIntegration(withScript._id, 'incoming');
});
});
describe('[/integrations.history]', () => {

Loading…
Cancel
Save