fix(Webhook Node): Fix URL params for webhooks (#6986)

Fixes:

https://community.n8n.io/t/empty-params-variables-in-webhook-node-after-upgrading-to-n8n-1-3-1/29624
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2023-08-25 13:28:32 +02:00 committed by GitHub
parent 87cf1d9c1b
commit 596b5695cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 26 deletions

View file

@ -194,6 +194,9 @@ export class ActiveWorkflowRunner implements IWebhookManager {
Logger.debug(`Received webhook "${httpMethod}" for path "${path}"`);
// Reset request parameters
request.params = {} as WebhookRequest['params'];
// Remove trailing slash
if (path.endsWith('/')) {
path = path.slice(0, -1);

View file

@ -56,6 +56,9 @@ export class TestWebhooks implements IWebhookManager {
const httpMethod = request.method;
let path = request.params.path;
// Reset request parameters
request.params = {} as WebhookRequest['params'];
// Remove trailing slash
if (path.endsWith('/')) {
path = path.slice(0, -1);

View file

@ -32,6 +32,9 @@ export class WaitingWebhooks implements IWebhookManager {
const { path: executionId, suffix } = req.params;
Logger.debug(`Received waiting-webhook "${req.method}" for execution "${executionId}"`);
// Reset request parameters
req.params = {} as WaitingWebhookRequest['params'];
const execution = await this.executionRepository.findSingleExecution(executionId, {
includeData: true,
unflattenData: true,

View file

@ -10,6 +10,7 @@ import { InternalHooks } from '@/InternalHooks';
import { getLogger } from '@/Logger';
import { NodeTypes } from '@/NodeTypes';
import { Push } from '@/push';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { mockInstance, initActiveWorkflowRunner } from './shared/utils';
import * as testDb from './shared/testDb';
@ -22,47 +23,43 @@ describe('Webhook API', () => {
let agent: SuperAgentTest;
beforeAll(async () => {
await testDb.init();
});
afterAll(async () => {
await testDb.terminate();
});
describe('Content-Type support', () => {
beforeAll(async () => {
await testDb.init();
const node = new WebhookTestingNode();
const user = await testDb.createUser();
await testDb.createWorkflow(
{
active: true,
nodes: [
{
name: 'Webhook',
type: node.description.name,
typeVersion: 1,
parameters: {
httpMethod: 'POST',
path: 'abcd',
},
id: '74786112-fb73-4d80-bd9a-43982939b801',
webhookId: '5ccef736-be16-4d10-b7fb-feed7a61ff22',
position: [740, 420],
},
],
},
user,
);
await testDb.createWorkflow(createWebhookWorkflow(node), user);
const nodeTypes = mockInstance(NodeTypes);
nodeTypes.getByName.mockReturnValue(node);
nodeTypes.getByNameAndVersion.mockReturnValue(node);
await initActiveWorkflowRunner();
const server = new (class extends AbstractServer {})();
await server.start();
agent = testAgent(server.app);
});
afterAll(async () => {
await testDb.truncate(['Workflow']);
});
test('should handle JSON', async () => {
const response = await agent.post('/webhook/abcd').send({ test: true });
expect(response.statusCode).toEqual(200);
expect(response.body).toEqual({ type: 'application/json', body: { test: true } });
expect(response.body).toEqual({
type: 'application/json',
body: { test: true },
params: {},
});
});
test('should handle XML', async () => {
@ -83,6 +80,7 @@ describe('Webhook API', () => {
inner: 'value',
},
},
params: {},
});
});
@ -95,6 +93,7 @@ describe('Webhook API', () => {
expect(response.body).toEqual({
type: 'application/x-www-form-urlencoded',
body: { x: '5', y: 'str', z: 'false' },
params: {},
});
});
@ -107,6 +106,7 @@ describe('Webhook API', () => {
expect(response.body).toEqual({
type: 'text/plain',
body: '{"key": "value"}',
params: {},
});
});
@ -133,6 +133,44 @@ describe('Webhook API', () => {
});
});
describe('Params support', () => {
beforeAll(async () => {
const node = new WebhookTestingNode();
const user = await testDb.createUser();
await testDb.createWorkflow(createWebhookWorkflow(node, ':variable', 'PATCH'), user);
const nodeTypes = mockInstance(NodeTypes);
nodeTypes.getByName.mockReturnValue(node);
nodeTypes.getByNameAndVersion.mockReturnValue(node);
await initActiveWorkflowRunner();
const server = new (class extends AbstractServer {})();
await server.start();
agent = testAgent(server.app);
});
afterAll(async () => {
await testDb.truncate(['Workflow']);
});
test('should handle params', async () => {
const response = await agent
.patch('/webhook/5ccef736-be16-4d10-b7fb-feed7a61ff22/test')
.send({ test: true });
expect(response.statusCode).toEqual(200);
expect(response.body).toEqual({
type: 'application/json',
body: { test: true },
params: {
variable: 'test',
},
});
await agent.post('/webhook/abcd').send({ test: true }).expect(404);
});
});
class WebhookTestingNode implements INodeType {
description: INodeTypeDescription = {
displayName: 'Webhook Testing Node',
@ -173,8 +211,28 @@ describe('Webhook API', () => {
webhookResponse: {
type: req.contentType,
body: req.body,
params: req.params,
},
};
}
}
const createWebhookWorkflow = (
node: WebhookTestingNode,
path = 'abcd',
httpMethod = 'POST',
): Partial<WorkflowEntity> => ({
active: true,
nodes: [
{
name: 'Webhook',
type: node.description.name,
typeVersion: 1,
parameters: { httpMethod, path },
id: '74786112-fb73-4d80-bd9a-43982939b801',
webhookId: '5ccef736-be16-4d10-b7fb-feed7a61ff22',
position: [740, 420],
},
],
});
});

View file

@ -127,7 +127,7 @@ export class Webhook extends Node {
const response: INodeExecutionData = {
json: {
headers: req.headers,
params: {},
params: req.params,
query: req.query,
body: req.body,
},
@ -207,7 +207,7 @@ export class Webhook extends Node {
binary: {},
json: {
headers: req.headers,
params: {},
params: req.params,
query: req.query,
body: data,
},
@ -263,7 +263,7 @@ export class Webhook extends Node {
binary: {},
json: {
headers: req.headers,
params: {},
params: req.params,
query: req.query,
body: {},
},