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 }, ) => IDataObject; export const prepareRequestBody = ( parameters: BodyParameter[], bodyType: string, version: number, defaultReducer: BodyParametersReducer, ) => { if (bodyType === 'json' && version >= 4) { return parameters.reduce((acc, entry) => { const value = entry.value; set(acc, entry.name, value); return acc; }, {} as IDataObject); } else { return parameters.reduce(defaultReducer, {}); } };