mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 21:07:28 -08:00
fix(Webhook Node): Backward compatible form-data parsing for non-array files (#7385)
Fixes https://community.n8n.io/t/possible-bug-0-added-to-end-of-files-sent-via-webhook/31169
This commit is contained in:
parent
7ed466db7f
commit
6479eb180f
|
@ -190,6 +190,15 @@ export function encodeWebhookResponse(
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const normalizeFormData = <T>(values: Record<string, T | T[]>) => {
|
||||||
|
for (const key in values) {
|
||||||
|
const value = values[key];
|
||||||
|
if (Array.isArray(value) && value.length === 1) {
|
||||||
|
values[key] = value[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a webhook
|
* Executes a webhook
|
||||||
*/
|
*/
|
||||||
|
@ -310,11 +319,8 @@ export async function executeWebhook(
|
||||||
});
|
});
|
||||||
req.body = await new Promise((resolve) => {
|
req.body = await new Promise((resolve) => {
|
||||||
form.parse(req, async (err, data, files) => {
|
form.parse(req, async (err, data, files) => {
|
||||||
for (const key in data) {
|
normalizeFormData(data);
|
||||||
if (Array.isArray(data[key]) && data[key].length === 1) {
|
normalizeFormData(files);
|
||||||
data[key] = data[key][0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolve({ data, files });
|
resolve({ data, files });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -116,20 +116,21 @@ describe('Webhook API', () => {
|
||||||
.field('field1', 'value1')
|
.field('field1', 'value1')
|
||||||
.field('field2', 'value2')
|
.field('field2', 'value2')
|
||||||
.field('field2', 'value3')
|
.field('field2', 'value3')
|
||||||
.attach('file', Buffer.from('random-text'))
|
.attach('file1', Buffer.from('random-text'))
|
||||||
|
.attach('file2', Buffer.from('random-text'))
|
||||||
|
.attach('file2', Buffer.from('random-text'))
|
||||||
.set('content-type', 'multipart/form-data');
|
.set('content-type', 'multipart/form-data');
|
||||||
|
|
||||||
expect(response.statusCode).toEqual(200);
|
expect(response.statusCode).toEqual(200);
|
||||||
expect(response.body.type).toEqual('multipart/form-data');
|
expect(response.body.type).toEqual('multipart/form-data');
|
||||||
const {
|
const { data, files } = response.body.body;
|
||||||
data,
|
|
||||||
files: {
|
|
||||||
file: [file],
|
|
||||||
},
|
|
||||||
} = response.body.body;
|
|
||||||
expect(data).toEqual({ field1: 'value1', field2: ['value2', 'value3'] });
|
expect(data).toEqual({ field1: 'value1', field2: ['value2', 'value3'] });
|
||||||
expect(file.mimetype).toEqual('application/octet-stream');
|
|
||||||
expect(readFileSync(file.filepath, 'utf-8')).toEqual('random-text');
|
expect(files.file1).not.toBeInstanceOf(Array);
|
||||||
|
expect(files.file1.mimetype).toEqual('application/octet-stream');
|
||||||
|
expect(readFileSync(files.file1.filepath, 'utf-8')).toEqual('random-text');
|
||||||
|
expect(files.file2).toBeInstanceOf(Array);
|
||||||
|
expect(files.file2.length).toEqual(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue