mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 20:54:07 -08:00
75541e91f2
Story: [PAY-846](https://linear.app/n8n/issue/PAY-846) | Related: https://github.com/n8n-io/n8n/pull/7225 For the S3 backend for external storage of binary data and execution data, the `getAsStream` method in the binary data manager interface used by FS and S3 will need to become async. This is a breaking change for nodes-base.
169 lines
4.3 KiB
TypeScript
169 lines
4.3 KiB
TypeScript
import type { IDataObject, INodeExecutionData, IOAuth2Options } from 'n8n-workflow';
|
|
import type { OptionsWithUri } from 'request-promise-native';
|
|
|
|
import set from 'lodash/set';
|
|
|
|
export type BodyParameter = { name: string; value: string };
|
|
|
|
export type IAuthDataSanitizeKeys = {
|
|
[key: string]: string[];
|
|
};
|
|
|
|
export const replaceNullValues = (item: INodeExecutionData) => {
|
|
if (item.json === null) {
|
|
item.json = {};
|
|
}
|
|
return item;
|
|
};
|
|
|
|
export function sanitizeUiMessage(request: OptionsWithUri, authDataKeys: IAuthDataSanitizeKeys) {
|
|
let sendRequest = request as unknown as IDataObject;
|
|
|
|
// Protect browser from sending large binary data
|
|
if (Buffer.isBuffer(sendRequest.body) && sendRequest.body.length > 250000) {
|
|
sendRequest = {
|
|
...request,
|
|
body: `Binary data got replaced with this text. Original was a Buffer with a size of ${request.body.length} byte.`,
|
|
};
|
|
}
|
|
|
|
// Remove credential information
|
|
for (const requestProperty of Object.keys(authDataKeys)) {
|
|
sendRequest = {
|
|
...sendRequest,
|
|
[requestProperty]: Object.keys(sendRequest[requestProperty] as object).reduce(
|
|
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
(acc: IDataObject, curr) => {
|
|
acc[curr] = authDataKeys[requestProperty].includes(curr)
|
|
? '** hidden **'
|
|
: (sendRequest[requestProperty] as IDataObject)[curr];
|
|
return acc;
|
|
},
|
|
{},
|
|
),
|
|
};
|
|
}
|
|
|
|
return sendRequest;
|
|
}
|
|
|
|
export const getOAuth2AdditionalParameters = (nodeCredentialType: string) => {
|
|
const oAuth2Options: { [credentialType: string]: IOAuth2Options } = {
|
|
bitlyOAuth2Api: {
|
|
tokenType: 'Bearer',
|
|
},
|
|
boxOAuth2Api: {
|
|
includeCredentialsOnRefreshOnBody: true,
|
|
},
|
|
ciscoWebexOAuth2Api: {
|
|
tokenType: 'Bearer',
|
|
},
|
|
clickUpOAuth2Api: {
|
|
keepBearer: false,
|
|
tokenType: 'Bearer',
|
|
},
|
|
goToWebinarOAuth2Api: {
|
|
tokenExpiredStatusCode: 403,
|
|
},
|
|
hubspotDeveloperApi: {
|
|
tokenType: 'Bearer',
|
|
includeCredentialsOnRefreshOnBody: true,
|
|
},
|
|
hubspotOAuth2Api: {
|
|
tokenType: 'Bearer',
|
|
includeCredentialsOnRefreshOnBody: true,
|
|
},
|
|
lineNotifyOAuth2Api: {
|
|
tokenType: 'Bearer',
|
|
},
|
|
linkedInOAuth2Api: {
|
|
tokenType: 'Bearer',
|
|
},
|
|
mailchimpOAuth2Api: {
|
|
tokenType: 'Bearer',
|
|
},
|
|
mauticOAuth2Api: {
|
|
includeCredentialsOnRefreshOnBody: true,
|
|
},
|
|
microsoftDynamicsOAuth2Api: {
|
|
property: 'id_token',
|
|
},
|
|
philipsHueOAuth2Api: {
|
|
tokenType: 'Bearer',
|
|
},
|
|
raindropOAuth2Api: {
|
|
includeCredentialsOnRefreshOnBody: true,
|
|
},
|
|
shopifyOAuth2Api: {
|
|
tokenType: 'Bearer',
|
|
keyToIncludeInAccessTokenHeader: 'X-Shopify-Access-Token',
|
|
},
|
|
slackOAuth2Api: {
|
|
tokenType: 'Bearer',
|
|
property: 'authed_user.access_token',
|
|
},
|
|
stravaOAuth2Api: {
|
|
includeCredentialsOnRefreshOnBody: true,
|
|
},
|
|
};
|
|
return oAuth2Options[nodeCredentialType];
|
|
};
|
|
|
|
//https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
|
export const binaryContentTypes = [
|
|
'image/',
|
|
'audio/',
|
|
'video/',
|
|
'application/octet-stream',
|
|
'application/gzip',
|
|
'application/zip',
|
|
'application/vnd.rar',
|
|
'application/epub+zip',
|
|
'application/x-bzip',
|
|
'application/x-bzip2',
|
|
'application/x-cdf',
|
|
'application/vnd.amazon.ebook',
|
|
'application/msword',
|
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
'application/vnd.ms-fontobject',
|
|
'application/vnd.oasis.opendocument.presentation',
|
|
'application/pdf',
|
|
'application/x-tar',
|
|
'application/vnd.visio',
|
|
'application/vnd.ms-excel',
|
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
'application/x-7z-compressed',
|
|
];
|
|
|
|
export type BodyParametersReducer = (
|
|
acc: IDataObject,
|
|
cur: { name: string; value: string },
|
|
) => Promise<IDataObject>;
|
|
|
|
export async function reduceAsync<T, R>(
|
|
arr: T[],
|
|
reducer: (acc: Awaited<Promise<R>>, cur: T) => Promise<R>,
|
|
init: Promise<R> = Promise.resolve({} as R),
|
|
): Promise<R> {
|
|
return arr.reduce(async (promiseAcc, item) => {
|
|
return reducer(await promiseAcc, item);
|
|
}, init);
|
|
}
|
|
|
|
export const prepareRequestBody = async (
|
|
parameters: BodyParameter[],
|
|
bodyType: string,
|
|
version: number,
|
|
defaultReducer: BodyParametersReducer,
|
|
) => {
|
|
if (bodyType === 'json' && version >= 4) {
|
|
return parameters.reduce(async (acc, entry) => {
|
|
const result = await acc;
|
|
set(result, entry.name, entry.value);
|
|
return result;
|
|
}, Promise.resolve({}));
|
|
} else {
|
|
return reduceAsync(parameters, defaultReducer);
|
|
}
|
|
};
|