mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 20:54:07 -08:00
fix(core): Improve handling of invalid objects in cleanupParameterData
(no-chanhelog) (#8910)
This commit is contained in:
parent
669bd830e9
commit
33ab781aef
|
@ -33,6 +33,7 @@ import { Agent, type AgentOptions } from 'https';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import isEmpty from 'lodash/isEmpty';
|
import isEmpty from 'lodash/isEmpty';
|
||||||
import pick from 'lodash/pick';
|
import pick from 'lodash/pick';
|
||||||
|
import { DateTime } from 'luxon';
|
||||||
import { extension, lookup } from 'mime-types';
|
import { extension, lookup } from 'mime-types';
|
||||||
import type {
|
import type {
|
||||||
BinaryHelperFunctions,
|
BinaryHelperFunctions,
|
||||||
|
@ -2096,7 +2097,7 @@ export async function getCredentials(
|
||||||
* Clean up parameter data to make sure that only valid data gets returned
|
* Clean up parameter data to make sure that only valid data gets returned
|
||||||
* INFO: Currently only converts Luxon Dates as we know for sure it will not be breaking
|
* INFO: Currently only converts Luxon Dates as we know for sure it will not be breaking
|
||||||
*/
|
*/
|
||||||
function cleanupParameterData(inputData: NodeParameterValueType): void {
|
export function cleanupParameterData(inputData: NodeParameterValueType): void {
|
||||||
if (typeof inputData !== 'object' || inputData === null) {
|
if (typeof inputData !== 'object' || inputData === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2107,14 +2108,15 @@ function cleanupParameterData(inputData: NodeParameterValueType): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof inputData === 'object') {
|
if (typeof inputData === 'object') {
|
||||||
Object.keys(inputData).forEach((key) => {
|
type Key = keyof typeof inputData;
|
||||||
if (typeof inputData[key as keyof typeof inputData] === 'object') {
|
(Object.keys(inputData) as Key[]).forEach((key) => {
|
||||||
if (inputData[key as keyof typeof inputData]?.constructor.name === 'DateTime') {
|
const value = inputData[key];
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
if (value instanceof DateTime) {
|
||||||
// Is a special luxon date so convert to string
|
// Is a special luxon date so convert to string
|
||||||
inputData[key as keyof typeof inputData] =
|
inputData[key] = value.toString();
|
||||||
inputData[key as keyof typeof inputData]?.toString();
|
|
||||||
} else {
|
} else {
|
||||||
cleanupParameterData(inputData[key as keyof typeof inputData]);
|
cleanupParameterData(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
cleanupParameterData,
|
||||||
copyInputItems,
|
copyInputItems,
|
||||||
getBinaryDataBuffer,
|
getBinaryDataBuffer,
|
||||||
parseIncomingMessage,
|
parseIncomingMessage,
|
||||||
|
@ -7,6 +8,7 @@ import {
|
||||||
removeEmptyBody,
|
removeEmptyBody,
|
||||||
setBinaryDataBuffer,
|
setBinaryDataBuffer,
|
||||||
} from '@/NodeExecuteFunctions';
|
} from '@/NodeExecuteFunctions';
|
||||||
|
import { DateTime } from 'luxon';
|
||||||
import { mkdtempSync, readFileSync } from 'fs';
|
import { mkdtempSync, readFileSync } from 'fs';
|
||||||
import type { IncomingMessage } from 'http';
|
import type { IncomingMessage } from 'http';
|
||||||
import { mock } from 'jest-mock-extended';
|
import { mock } from 'jest-mock-extended';
|
||||||
|
@ -18,6 +20,7 @@ import type {
|
||||||
IRequestOptions,
|
IRequestOptions,
|
||||||
ITaskDataConnections,
|
ITaskDataConnections,
|
||||||
IWorkflowExecuteAdditionalData,
|
IWorkflowExecuteAdditionalData,
|
||||||
|
NodeParameterValue,
|
||||||
Workflow,
|
Workflow,
|
||||||
WorkflowHooks,
|
WorkflowHooks,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
@ -414,6 +417,29 @@ describe('NodeExecuteFunctions', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('cleanupParameterData', () => {
|
||||||
|
it('should stringify Luxon dates in-place', () => {
|
||||||
|
const input = { x: 1, y: DateTime.now() as unknown as NodeParameterValue };
|
||||||
|
expect(typeof input.y).toBe('object');
|
||||||
|
cleanupParameterData(input);
|
||||||
|
expect(typeof input.y).toBe('string');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle objects with nameless constructors', () => {
|
||||||
|
const input = { x: 1, y: { constructor: {} } as NodeParameterValue };
|
||||||
|
expect(typeof input.y).toBe('object');
|
||||||
|
cleanupParameterData(input);
|
||||||
|
expect(typeof input.y).toBe('object');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle objects without a constructor', () => {
|
||||||
|
const input = { x: 1, y: { constructor: undefined } as unknown as NodeParameterValue };
|
||||||
|
expect(typeof input.y).toBe('object');
|
||||||
|
cleanupParameterData(input);
|
||||||
|
expect(typeof input.y).toBe('object');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('copyInputItems', () => {
|
describe('copyInputItems', () => {
|
||||||
it('should pick only selected properties', () => {
|
it('should pick only selected properties', () => {
|
||||||
const output = copyInputItems(
|
const output = copyInputItems(
|
||||||
|
|
Loading…
Reference in a new issue