mirror of
https://github.com/n8n-io/n8n.git
synced 2026-08-29 01:39:24 +08:00
Merge commit from fork
* enforce content type multipart/form-data when we handle body.files * fix unit tests
This commit is contained in:
@@ -18,6 +18,7 @@ import type {
|
||||
IBinaryData,
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
import * as a from 'node:assert';
|
||||
|
||||
import { cssVariables } from './constants';
|
||||
import { validateAuth } from './GenericFunctions';
|
||||
@@ -566,6 +567,7 @@ export class ChatTrigger extends Node {
|
||||
|
||||
private async handleFormData(context: IWebhookFunctions) {
|
||||
const req = context.getRequestObject() as MultiPartFormData.Request;
|
||||
a.ok(req.contentType === 'multipart/form-data', 'Expected multipart/form-data');
|
||||
const options = context.getNodeParameter('options', {}) as IDataObject;
|
||||
const { data, files } = req.body;
|
||||
|
||||
|
||||
@@ -172,7 +172,10 @@ describe('Form Node', () => {
|
||||
});
|
||||
|
||||
it('should return form data for POST request', async () => {
|
||||
mockWebhookFunctions.getRequestObject.mockReturnValue({ method: 'POST' } as Request);
|
||||
mockWebhookFunctions.getRequestObject.mockReturnValue({
|
||||
method: 'POST',
|
||||
contentType: 'multipart/form-data',
|
||||
} as Request);
|
||||
mockWebhookFunctions.getParentNodes.mockReturnValue([
|
||||
{
|
||||
type: 'n8n-nodes-base.formTrigger',
|
||||
|
||||
@@ -148,7 +148,11 @@ describe('FormTrigger', () => {
|
||||
formFields: { values: formFields },
|
||||
},
|
||||
},
|
||||
request: { method: 'POST' },
|
||||
request: {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'multipart/form-data' },
|
||||
contentType: 'multipart/form-data',
|
||||
},
|
||||
bodyData,
|
||||
});
|
||||
|
||||
@@ -317,7 +321,11 @@ describe('FormTrigger', () => {
|
||||
formFields: { values: formFields },
|
||||
},
|
||||
},
|
||||
request: { method: 'POST' },
|
||||
request: {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'multipart/form-data' },
|
||||
contentType: 'multipart/form-data',
|
||||
},
|
||||
bodyData,
|
||||
});
|
||||
|
||||
|
||||
@@ -542,7 +542,10 @@ describe('FormTrigger, formWebhook', () => {
|
||||
|
||||
executeFunctions.getNodeParameter.calledWith('formFields.values').mockReturnValue(formFields);
|
||||
executeFunctions.getResponseObject.mockReturnValue({ status: mockStatus, end: mockEnd } as any);
|
||||
executeFunctions.getRequestObject.mockReturnValue({ method: 'POST' } as any);
|
||||
executeFunctions.getRequestObject.mockReturnValue({
|
||||
method: 'POST',
|
||||
contentType: 'multipart/form-data',
|
||||
} as any);
|
||||
executeFunctions.getBodyData.mockReturnValue({ data: bodyData, files: {} });
|
||||
|
||||
const result = await formWebhook(executeFunctions);
|
||||
@@ -1310,7 +1313,9 @@ jest.mock('luxon', () => ({
|
||||
|
||||
describe('prepareFormReturnItem', () => {
|
||||
const mockContext = mock<IWebhookFunctions>({
|
||||
getRequestObject: jest.fn().mockReturnValue({ method: 'GET', query: {} }),
|
||||
getRequestObject: jest
|
||||
.fn()
|
||||
.mockReturnValue({ method: 'GET', query: {}, contentType: 'multipart/form-data' }),
|
||||
nodeHelpers: mock({
|
||||
copyBinaryFile: jest.fn().mockResolvedValue({}),
|
||||
}),
|
||||
@@ -1456,6 +1461,7 @@ describe('prepareFormReturnItem', () => {
|
||||
mockContext.getRequestObject.mockReturnValue({
|
||||
method: 'POST',
|
||||
query: { param: 'value' },
|
||||
contentType: 'multipart/form-data',
|
||||
} as unknown as Request);
|
||||
|
||||
const result = await prepareFormReturnItem(mockContext, [], 'test');
|
||||
@@ -1467,6 +1473,7 @@ describe('prepareFormReturnItem', () => {
|
||||
mockContext.getRequestObject.mockReturnValue({
|
||||
method: 'POST',
|
||||
query: {},
|
||||
contentType: 'multipart/form-data',
|
||||
} as unknown as Request);
|
||||
|
||||
const result = await prepareFormReturnItem(mockContext, [], 'test');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Response } from 'express';
|
||||
import isbot from 'isbot';
|
||||
import * as a from 'node:assert';
|
||||
import { DateTime } from 'luxon';
|
||||
import type {
|
||||
INodeExecutionData,
|
||||
@@ -352,6 +353,8 @@ export async function prepareFormReturnItem(
|
||||
mode: 'test' | 'production',
|
||||
useWorkflowTimezone: boolean = false,
|
||||
) {
|
||||
const req = context.getRequestObject() as MultiPartFormData.Request;
|
||||
a.ok(req.contentType === 'multipart/form-data', 'Expected multipart/form-data');
|
||||
const bodyData = (context.getBodyData().data as IDataObject) ?? {};
|
||||
const files = (context.getBodyData().files as IDataObject) ?? {};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import type {
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
import { BINARY_ENCODING, NodeOperationError, Node } from 'n8n-workflow';
|
||||
import * as a from 'node:assert';
|
||||
import { pipeline } from 'stream/promises';
|
||||
import { file as tmpFile } from 'tmp-promise';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
@@ -316,6 +317,7 @@ export class Webhook extends Node {
|
||||
prepareOutput: (data: INodeExecutionData) => INodeExecutionData[][],
|
||||
) {
|
||||
const req = context.getRequestObject() as MultiPartFormData.Request;
|
||||
a.ok(req.contentType === 'multipart/form-data', 'Expected multipart/form-data');
|
||||
const options = context.getNodeParameter('options', {}) as IDataObject;
|
||||
const { data, files } = req.body;
|
||||
|
||||
|
||||
@@ -330,6 +330,7 @@ describe('Send and Wait utils tests', () => {
|
||||
it('should handle customForm POST webhook', async () => {
|
||||
mockWebhookFunctions.getRequestObject.mockReturnValue({
|
||||
method: 'POST',
|
||||
contentType: 'multipart/form-data',
|
||||
} as any);
|
||||
mockWebhookFunctions.getNode.mockReturnValue({} as any);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user