n8n-core 1.78.0 → 1.79.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/build.tsbuildinfo +1 -1
  2. package/dist/credentials.d.ts +1 -0
  3. package/dist/credentials.js +7 -0
  4. package/dist/credentials.js.map +1 -1
  5. package/dist/execution-engine/active-workflows.d.ts +2 -1
  6. package/dist/execution-engine/active-workflows.js.map +1 -1
  7. package/dist/execution-engine/execution-lifecycle-hooks.d.ts +24 -0
  8. package/dist/execution-engine/execution-lifecycle-hooks.js +30 -0
  9. package/dist/execution-engine/execution-lifecycle-hooks.js.map +1 -0
  10. package/dist/execution-engine/index.d.ts +2 -0
  11. package/dist/execution-engine/index.js +4 -0
  12. package/dist/execution-engine/index.js.map +1 -1
  13. package/dist/execution-engine/interfaces.d.ts +7 -0
  14. package/dist/execution-engine/interfaces.js +3 -0
  15. package/dist/execution-engine/interfaces.js.map +1 -0
  16. package/dist/execution-engine/node-execution-context/credentials-test-context.js +4 -3
  17. package/dist/execution-engine/node-execution-context/credentials-test-context.js.map +1 -1
  18. package/dist/execution-engine/node-execution-context/execute-context.d.ts +3 -1
  19. package/dist/execution-engine/node-execution-context/execute-context.js +27 -15
  20. package/dist/execution-engine/node-execution-context/execute-context.js.map +1 -1
  21. package/dist/execution-engine/node-execution-context/execute-single-context.d.ts +1 -1
  22. package/dist/execution-engine/node-execution-context/execute-single-context.js +9 -7
  23. package/dist/execution-engine/node-execution-context/execute-single-context.js.map +1 -1
  24. package/dist/execution-engine/node-execution-context/hook-context.js +5 -4
  25. package/dist/execution-engine/node-execution-context/hook-context.js.map +1 -1
  26. package/dist/execution-engine/node-execution-context/index.d.ts +6 -0
  27. package/dist/execution-engine/node-execution-context/index.js +26 -1
  28. package/dist/execution-engine/node-execution-context/index.js.map +1 -1
  29. package/dist/execution-engine/node-execution-context/load-options-context.js +4 -3
  30. package/dist/execution-engine/node-execution-context/load-options-context.js.map +1 -1
  31. package/dist/execution-engine/node-execution-context/node-execution-context.d.ts +1 -1
  32. package/dist/execution-engine/node-execution-context/poll-context.js +8 -5
  33. package/dist/execution-engine/node-execution-context/poll-context.js.map +1 -1
  34. package/dist/execution-engine/node-execution-context/supply-data-context.js +23 -15
  35. package/dist/execution-engine/node-execution-context/supply-data-context.js.map +1 -1
  36. package/dist/execution-engine/node-execution-context/trigger-context.js +10 -6
  37. package/dist/execution-engine/node-execution-context/trigger-context.js.map +1 -1
  38. package/dist/execution-engine/node-execution-context/utils/binary-helper-functions.d.ts +10 -0
  39. package/dist/execution-engine/node-execution-context/utils/binary-helper-functions.js +183 -0
  40. package/dist/execution-engine/node-execution-context/utils/binary-helper-functions.js.map +1 -0
  41. package/dist/execution-engine/node-execution-context/utils/construct-execution-metadata.d.ts +4 -0
  42. package/dist/execution-engine/node-execution-context/utils/construct-execution-metadata.js +11 -0
  43. package/dist/execution-engine/node-execution-context/utils/construct-execution-metadata.js.map +1 -0
  44. package/dist/execution-engine/node-execution-context/utils/copy-input-items.d.ts +2 -0
  45. package/dist/execution-engine/node-execution-context/utils/copy-input-items.js +19 -0
  46. package/dist/execution-engine/node-execution-context/utils/copy-input-items.js.map +1 -0
  47. package/dist/execution-engine/node-execution-context/utils/deduplication-helper-functions.d.ts +2 -0
  48. package/dist/execution-engine/node-execution-context/utils/deduplication-helper-functions.js +38 -0
  49. package/dist/execution-engine/node-execution-context/utils/deduplication-helper-functions.js.map +1 -0
  50. package/dist/execution-engine/node-execution-context/utils/file-system-helper-functions.d.ts +3 -0
  51. package/dist/execution-engine/node-execution-context/utils/file-system-helper-functions.js +98 -0
  52. package/dist/execution-engine/node-execution-context/utils/file-system-helper-functions.js.map +1 -0
  53. package/dist/execution-engine/node-execution-context/utils/get-input-connection-data.d.ts +1 -1
  54. package/dist/execution-engine/node-execution-context/utils/get-input-connection-data.js +2 -2
  55. package/dist/execution-engine/node-execution-context/utils/get-input-connection-data.js.map +1 -1
  56. package/dist/execution-engine/node-execution-context/utils/normalize-items.d.ts +2 -0
  57. package/dist/execution-engine/node-execution-context/utils/normalize-items.js +36 -0
  58. package/dist/execution-engine/node-execution-context/utils/normalize-items.js.map +1 -0
  59. package/dist/execution-engine/node-execution-context/utils/parse-incoming-message.d.ts +16 -0
  60. package/dist/execution-engine/node-execution-context/utils/parse-incoming-message.js +57 -0
  61. package/dist/execution-engine/node-execution-context/utils/parse-incoming-message.js.map +1 -0
  62. package/dist/execution-engine/node-execution-context/utils/request-helper-functions.d.ts +16 -0
  63. package/dist/execution-engine/node-execution-context/utils/request-helper-functions.js +1158 -0
  64. package/dist/execution-engine/node-execution-context/utils/request-helper-functions.js.map +1 -0
  65. package/dist/execution-engine/node-execution-context/utils/return-json-array.d.ts +2 -0
  66. package/dist/execution-engine/node-execution-context/utils/return-json-array.js +19 -0
  67. package/dist/execution-engine/node-execution-context/utils/return-json-array.js.map +1 -0
  68. package/dist/execution-engine/node-execution-context/utils/scheduling-helper-functions.d.ts +2 -0
  69. package/dist/execution-engine/node-execution-context/utils/scheduling-helper-functions.js +13 -0
  70. package/dist/execution-engine/node-execution-context/utils/scheduling-helper-functions.js.map +1 -0
  71. package/dist/execution-engine/node-execution-context/utils/ssh-tunnel-helper-functions.d.ts +2 -0
  72. package/dist/execution-engine/node-execution-context/utils/ssh-tunnel-helper-functions.js +13 -0
  73. package/dist/execution-engine/node-execution-context/utils/ssh-tunnel-helper-functions.js.map +1 -0
  74. package/dist/execution-engine/node-execution-context/utils/webhook-helper-functions.d.ts +3 -0
  75. package/dist/execution-engine/node-execution-context/utils/webhook-helper-functions.js +31 -0
  76. package/dist/execution-engine/node-execution-context/utils/webhook-helper-functions.js.map +1 -0
  77. package/dist/execution-engine/node-execution-context/webhook-context.js +9 -6
  78. package/dist/execution-engine/node-execution-context/webhook-context.js.map +1 -1
  79. package/dist/execution-engine/triggers-and-pollers.d.ts +2 -1
  80. package/dist/execution-engine/triggers-and-pollers.js +19 -23
  81. package/dist/execution-engine/triggers-and-pollers.js.map +1 -1
  82. package/dist/execution-engine/workflow-execute.d.ts +0 -1
  83. package/dist/execution-engine/workflow-execute.js +21 -23
  84. package/dist/execution-engine/workflow-execute.js.map +1 -1
  85. package/dist/node-execute-functions.d.ts +1 -62
  86. package/dist/node-execute-functions.js +0 -1626
  87. package/dist/node-execute-functions.js.map +1 -1
  88. package/package.json +4 -4
@@ -0,0 +1,1158 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.getRequestHelperFunctions = exports.removeEmptyBody = exports.createFormDataObject = void 0;
40
+ exports.invokeAxios = invokeAxios;
41
+ exports.parseRequestObject = parseRequestObject;
42
+ exports.proxyRequestToAxios = proxyRequestToAxios;
43
+ exports.convertN8nRequestToAxios = convertN8nRequestToAxios;
44
+ exports.httpRequest = httpRequest;
45
+ exports.applyPaginationRequestData = applyPaginationRequestData;
46
+ exports.requestOAuth2 = requestOAuth2;
47
+ exports.requestOAuth1 = requestOAuth1;
48
+ exports.httpRequestWithAuthentication = httpRequestWithAuthentication;
49
+ exports.requestWithAuthentication = requestWithAuthentication;
50
+ const client_oauth2_1 = require("@n8n/client-oauth2");
51
+ const di_1 = require("@n8n/di");
52
+ const axios_1 = __importDefault(require("axios"));
53
+ const crypto_1 = __importStar(require("crypto"));
54
+ const form_data_1 = __importDefault(require("form-data"));
55
+ const http_1 = require("http");
56
+ const https_1 = require("https");
57
+ const get_1 = __importDefault(require("lodash/get"));
58
+ const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
59
+ const merge_1 = __importDefault(require("lodash/merge"));
60
+ const pick_1 = __importDefault(require("lodash/pick"));
61
+ const n8n_workflow_1 = require("n8n-workflow");
62
+ const oauth_1_0a_1 = __importDefault(require("oauth-1.0a"));
63
+ const qs_1 = require("qs");
64
+ const stream_1 = require("stream");
65
+ const url_1 = __importStar(require("url"));
66
+ const logger_1 = require("../../../logging/logger");
67
+ const binary_helper_functions_1 = require("./binary-helper-functions");
68
+ const parse_incoming_message_1 = require("./parse-incoming-message");
69
+ axios_1.default.defaults.timeout = 300000;
70
+ axios_1.default.defaults.headers.post = {};
71
+ axios_1.default.defaults.headers.put = {};
72
+ axios_1.default.defaults.headers.patch = {};
73
+ axios_1.default.defaults.paramsSerializer = (params) => {
74
+ if (params instanceof url_1.URLSearchParams) {
75
+ return params.toString();
76
+ }
77
+ return (0, qs_1.stringify)(params, { arrayFormat: 'indices' });
78
+ };
79
+ axios_1.default.interceptors.request.use((config) => {
80
+ if (config.data === undefined) {
81
+ config.headers.setContentType(false, false);
82
+ }
83
+ return config;
84
+ });
85
+ const validateUrl = (url) => {
86
+ if (!url)
87
+ return false;
88
+ try {
89
+ new url_1.URL(url);
90
+ return true;
91
+ }
92
+ catch (error) {
93
+ return false;
94
+ }
95
+ };
96
+ function searchForHeader(config, headerName) {
97
+ if (config.headers === undefined) {
98
+ return undefined;
99
+ }
100
+ const headerNames = Object.keys(config.headers);
101
+ headerName = headerName.toLowerCase();
102
+ return headerNames.find((thisHeader) => thisHeader.toLowerCase() === headerName);
103
+ }
104
+ const getHostFromRequestObject = (requestObject) => {
105
+ try {
106
+ const url = (requestObject.url ?? requestObject.uri);
107
+ return new url_1.URL(url, requestObject.baseURL).hostname;
108
+ }
109
+ catch (error) {
110
+ return null;
111
+ }
112
+ };
113
+ const getBeforeRedirectFn = (agentOptions, axiosConfig) => (redirectedRequest) => {
114
+ const redirectAgent = new https_1.Agent({
115
+ ...agentOptions,
116
+ servername: redirectedRequest.hostname,
117
+ });
118
+ redirectedRequest.agent = redirectAgent;
119
+ redirectedRequest.agents.https = redirectAgent;
120
+ if (axiosConfig.headers?.Authorization) {
121
+ redirectedRequest.headers.Authorization = axiosConfig.headers.Authorization;
122
+ }
123
+ if (axiosConfig.auth) {
124
+ redirectedRequest.auth = `${axiosConfig.auth.username}:${axiosConfig.auth.password}`;
125
+ }
126
+ };
127
+ function digestAuthAxiosConfig(axiosConfig, response, auth) {
128
+ const authDetails = response.headers['www-authenticate']
129
+ .split(',')
130
+ .map((v) => v.split('='));
131
+ if (authDetails) {
132
+ const nonceCount = '000000001';
133
+ const cnonce = crypto_1.default.randomBytes(24).toString('hex');
134
+ const realm = authDetails
135
+ .find((el) => el[0].toLowerCase().indexOf('realm') > -1)[1]
136
+ .replace(/"/g, '');
137
+ const opaqueKV = authDetails.find((el) => el[0].toLowerCase().indexOf('opaque') > -1);
138
+ const opaque = opaqueKV ? opaqueKV[1].replace(/"/g, '') : undefined;
139
+ const nonce = authDetails
140
+ .find((el) => el[0].toLowerCase().indexOf('nonce') > -1)[1]
141
+ .replace(/"/g, '');
142
+ const ha1 = crypto_1.default
143
+ .createHash('md5')
144
+ .update(`${auth?.username}:${realm}:${auth?.password}`)
145
+ .digest('hex');
146
+ const urlURL = new url_1.default.URL(axios_1.default.getUri(axiosConfig));
147
+ const path = urlURL.pathname + urlURL.search;
148
+ const ha2 = crypto_1.default
149
+ .createHash('md5')
150
+ .update(`${axiosConfig.method ?? 'GET'}:${path}`)
151
+ .digest('hex');
152
+ const response = crypto_1.default
153
+ .createHash('md5')
154
+ .update(`${ha1}:${nonce}:${nonceCount}:${cnonce}:auth:${ha2}`)
155
+ .digest('hex');
156
+ let authorization = `Digest username="${auth?.username}",realm="${realm}",` +
157
+ `nonce="${nonce}",uri="${path}",qop="auth",algorithm="MD5",` +
158
+ `response="${response}",nc="${nonceCount}",cnonce="${cnonce}"`;
159
+ if (opaque) {
160
+ authorization += `,opaque="${opaque}"`;
161
+ }
162
+ if (axiosConfig.headers) {
163
+ axiosConfig.headers.authorization = authorization;
164
+ }
165
+ else {
166
+ axiosConfig.headers = { authorization };
167
+ }
168
+ }
169
+ return axiosConfig;
170
+ }
171
+ async function invokeAxios(axiosConfig, authOptions = {}) {
172
+ try {
173
+ return await (0, axios_1.default)(axiosConfig);
174
+ }
175
+ catch (error) {
176
+ if (authOptions.sendImmediately !== false || !(error instanceof axios_1.default.AxiosError))
177
+ throw error;
178
+ const { response } = error;
179
+ if (response?.status !== 401 || !response.headers['www-authenticate']?.includes('nonce')) {
180
+ throw error;
181
+ }
182
+ const { auth } = axiosConfig;
183
+ delete axiosConfig.auth;
184
+ axiosConfig = digestAuthAxiosConfig(axiosConfig, response, auth);
185
+ return await (0, axios_1.default)(axiosConfig);
186
+ }
187
+ }
188
+ const pushFormDataValue = (form, key, value) => {
189
+ if (value?.hasOwnProperty('value') && value.hasOwnProperty('options')) {
190
+ form.append(key, value.value, value.options);
191
+ }
192
+ else {
193
+ form.append(key, value);
194
+ }
195
+ };
196
+ const createFormDataObject = (data) => {
197
+ const formData = new form_data_1.default();
198
+ const keys = Object.keys(data);
199
+ keys.forEach((key) => {
200
+ const formField = data[key];
201
+ if (formField instanceof Array) {
202
+ formField.forEach((item) => {
203
+ pushFormDataValue(formData, key, item);
204
+ });
205
+ }
206
+ else {
207
+ pushFormDataValue(formData, key, formField);
208
+ }
209
+ });
210
+ return formData;
211
+ };
212
+ exports.createFormDataObject = createFormDataObject;
213
+ async function generateContentLengthHeader(config) {
214
+ if (!(config.data instanceof form_data_1.default)) {
215
+ return;
216
+ }
217
+ try {
218
+ const length = await new Promise((res, rej) => {
219
+ config.data.getLength((error, dataLength) => {
220
+ if (error)
221
+ rej(error);
222
+ else
223
+ res(dataLength);
224
+ });
225
+ });
226
+ config.headers = {
227
+ ...config.headers,
228
+ 'content-length': length,
229
+ };
230
+ }
231
+ catch (error) {
232
+ di_1.Container.get(logger_1.Logger).error('Unable to calculate form data length', { error });
233
+ }
234
+ }
235
+ async function parseRequestObject(requestObject) {
236
+ const axiosConfig = {};
237
+ if (requestObject.headers !== undefined) {
238
+ axiosConfig.headers = requestObject.headers;
239
+ }
240
+ const contentTypeHeaderKeyName = axiosConfig.headers &&
241
+ Object.keys(axiosConfig.headers).find((headerName) => headerName.toLowerCase() === 'content-type');
242
+ const contentType = contentTypeHeaderKeyName &&
243
+ axiosConfig.headers?.[contentTypeHeaderKeyName];
244
+ if (contentType === 'application/x-www-form-urlencoded' && requestObject.formData === undefined) {
245
+ if (typeof requestObject.body === 'string') {
246
+ axiosConfig.data = requestObject.body;
247
+ }
248
+ else {
249
+ const allData = Object.assign(requestObject.body || {}, requestObject.form || {});
250
+ if (requestObject.useQuerystring === true) {
251
+ axiosConfig.data = (0, qs_1.stringify)(allData, { arrayFormat: 'repeat' });
252
+ }
253
+ else {
254
+ axiosConfig.data = (0, qs_1.stringify)(allData);
255
+ }
256
+ }
257
+ }
258
+ else if (contentType?.includes('multipart/form-data')) {
259
+ if (requestObject.formData !== undefined && requestObject.formData instanceof form_data_1.default) {
260
+ axiosConfig.data = requestObject.formData;
261
+ }
262
+ else {
263
+ const allData = {
264
+ ...requestObject.body,
265
+ ...requestObject.formData,
266
+ };
267
+ axiosConfig.data = (0, exports.createFormDataObject)(allData);
268
+ }
269
+ delete axiosConfig.headers?.[contentTypeHeaderKeyName];
270
+ const headers = axiosConfig.data.getHeaders();
271
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, headers);
272
+ await generateContentLengthHeader(axiosConfig);
273
+ }
274
+ else {
275
+ if (requestObject.form !== undefined && requestObject.body === undefined) {
276
+ axiosConfig.data =
277
+ typeof requestObject.form === 'string'
278
+ ? (0, qs_1.stringify)(requestObject.form, { format: 'RFC3986' })
279
+ : (0, qs_1.stringify)(requestObject.form).toString();
280
+ if (axiosConfig.headers !== undefined) {
281
+ const headerName = searchForHeader(axiosConfig, 'content-type');
282
+ if (headerName) {
283
+ delete axiosConfig.headers[headerName];
284
+ }
285
+ axiosConfig.headers['Content-Type'] = 'application/x-www-form-urlencoded';
286
+ }
287
+ else {
288
+ axiosConfig.headers = {
289
+ 'Content-Type': 'application/x-www-form-urlencoded',
290
+ };
291
+ }
292
+ }
293
+ else if (requestObject.formData !== undefined) {
294
+ if (axiosConfig.headers !== undefined) {
295
+ const headers = Object.keys(axiosConfig.headers);
296
+ headers.forEach((header) => {
297
+ if (header.toLowerCase() === 'content-type') {
298
+ delete axiosConfig.headers?.[header];
299
+ }
300
+ });
301
+ }
302
+ if (requestObject.formData instanceof form_data_1.default) {
303
+ axiosConfig.data = requestObject.formData;
304
+ }
305
+ else {
306
+ axiosConfig.data = (0, exports.createFormDataObject)(requestObject.formData);
307
+ }
308
+ const headers = axiosConfig.data.getHeaders();
309
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, headers);
310
+ await generateContentLengthHeader(axiosConfig);
311
+ }
312
+ else if (requestObject.body !== undefined) {
313
+ if (requestObject.form !== undefined && requestObject.body) {
314
+ requestObject.body = Object.assign(requestObject.body, requestObject.form);
315
+ }
316
+ axiosConfig.data = requestObject.body;
317
+ }
318
+ }
319
+ if (requestObject.uri !== undefined) {
320
+ axiosConfig.url = requestObject.uri?.toString();
321
+ }
322
+ if (requestObject.url !== undefined) {
323
+ axiosConfig.url = requestObject.url?.toString();
324
+ }
325
+ if (requestObject.baseURL !== undefined) {
326
+ axiosConfig.baseURL = requestObject.baseURL?.toString();
327
+ }
328
+ if (requestObject.method !== undefined) {
329
+ axiosConfig.method = requestObject.method;
330
+ }
331
+ if (requestObject.qs !== undefined && Object.keys(requestObject.qs).length > 0) {
332
+ axiosConfig.params = requestObject.qs;
333
+ }
334
+ function hasArrayFormatOptions(arg) {
335
+ if (typeof arg.qsStringifyOptions === 'object' &&
336
+ arg.qsStringifyOptions !== null &&
337
+ !Array.isArray(arg.qsStringifyOptions) &&
338
+ 'arrayFormat' in arg.qsStringifyOptions) {
339
+ return true;
340
+ }
341
+ return false;
342
+ }
343
+ if (requestObject.useQuerystring === true ||
344
+ (hasArrayFormatOptions(requestObject) &&
345
+ requestObject.qsStringifyOptions.arrayFormat === 'repeat')) {
346
+ axiosConfig.paramsSerializer = (params) => {
347
+ return (0, qs_1.stringify)(params, { arrayFormat: 'repeat' });
348
+ };
349
+ }
350
+ else if (requestObject.useQuerystring === false) {
351
+ axiosConfig.paramsSerializer = (params) => {
352
+ return (0, qs_1.stringify)(params, { arrayFormat: 'indices' });
353
+ };
354
+ }
355
+ if (hasArrayFormatOptions(requestObject) &&
356
+ requestObject.qsStringifyOptions.arrayFormat === 'brackets') {
357
+ axiosConfig.paramsSerializer = (params) => {
358
+ return (0, qs_1.stringify)(params, { arrayFormat: 'brackets' });
359
+ };
360
+ }
361
+ if (requestObject.auth !== undefined) {
362
+ if (requestObject.auth.bearer !== undefined) {
363
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, {
364
+ Authorization: `Bearer ${requestObject.auth.bearer}`,
365
+ });
366
+ }
367
+ else {
368
+ const authObj = requestObject.auth;
369
+ axiosConfig.auth = {
370
+ username: (authObj.user || authObj.username),
371
+ password: (authObj.password || authObj.pass),
372
+ };
373
+ }
374
+ }
375
+ if (requestObject.json === true) {
376
+ const acceptHeaderExists = axiosConfig.headers === undefined
377
+ ? false
378
+ : Object.keys(axiosConfig.headers)
379
+ .map((headerKey) => headerKey.toLowerCase())
380
+ .includes('accept');
381
+ if (!acceptHeaderExists) {
382
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, {
383
+ Accept: 'application/json',
384
+ });
385
+ }
386
+ }
387
+ if (requestObject.json === false || requestObject.json === undefined) {
388
+ axiosConfig.transformResponse = (res) => res;
389
+ }
390
+ const { method } = requestObject;
391
+ if ((requestObject.followRedirect !== false &&
392
+ (!method || method === 'GET' || method === 'HEAD')) ||
393
+ requestObject.followAllRedirects) {
394
+ axiosConfig.maxRedirects = requestObject.maxRedirects;
395
+ }
396
+ else {
397
+ axiosConfig.maxRedirects = 0;
398
+ }
399
+ const host = getHostFromRequestObject(requestObject);
400
+ const agentOptions = { ...requestObject.agentOptions };
401
+ if (host) {
402
+ agentOptions.servername = host;
403
+ }
404
+ if (requestObject.rejectUnauthorized === false) {
405
+ agentOptions.rejectUnauthorized = false;
406
+ agentOptions.secureOptions = crypto_1.default.constants.SSL_OP_LEGACY_SERVER_CONNECT;
407
+ }
408
+ axiosConfig.httpsAgent = new https_1.Agent(agentOptions);
409
+ axiosConfig.beforeRedirect = getBeforeRedirectFn(agentOptions, axiosConfig);
410
+ if (requestObject.timeout !== undefined) {
411
+ axiosConfig.timeout = requestObject.timeout;
412
+ }
413
+ if (requestObject.proxy !== undefined) {
414
+ if (typeof requestObject.proxy === 'string') {
415
+ try {
416
+ const url = new url_1.URL(requestObject.proxy);
417
+ const host = url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname;
418
+ axiosConfig.proxy = {
419
+ host,
420
+ port: parseInt(url.port, 10),
421
+ protocol: url.protocol,
422
+ };
423
+ if (!url.port) {
424
+ if (url.protocol === 'http') {
425
+ axiosConfig.proxy.port = 80;
426
+ }
427
+ else if (url.protocol === 'https') {
428
+ axiosConfig.proxy.port = 443;
429
+ }
430
+ }
431
+ if (url.username || url.password) {
432
+ axiosConfig.proxy.auth = {
433
+ username: url.username,
434
+ password: url.password,
435
+ };
436
+ }
437
+ }
438
+ catch (error) {
439
+ if (requestObject.proxy.includes('@')) {
440
+ const [userpass, hostport] = requestObject.proxy.split('@');
441
+ const [username, password] = userpass.split(':');
442
+ const [hostname, port] = hostport.split(':');
443
+ const host = hostname.startsWith('[') ? hostname.slice(1, -1) : hostname;
444
+ axiosConfig.proxy = {
445
+ host,
446
+ port: parseInt(port, 10),
447
+ protocol: 'http',
448
+ auth: {
449
+ username,
450
+ password,
451
+ },
452
+ };
453
+ }
454
+ else if (requestObject.proxy.includes(':')) {
455
+ const [hostname, port] = requestObject.proxy.split(':');
456
+ axiosConfig.proxy = {
457
+ host: hostname,
458
+ port: parseInt(port, 10),
459
+ protocol: 'http',
460
+ };
461
+ }
462
+ else {
463
+ axiosConfig.proxy = {
464
+ host: requestObject.proxy,
465
+ port: 80,
466
+ protocol: 'http',
467
+ };
468
+ }
469
+ }
470
+ }
471
+ else {
472
+ axiosConfig.proxy = requestObject.proxy;
473
+ }
474
+ }
475
+ if (requestObject.useStream) {
476
+ axiosConfig.responseType = 'stream';
477
+ }
478
+ else if (requestObject.encoding === null) {
479
+ axiosConfig.responseType = 'arraybuffer';
480
+ }
481
+ const allHeaders = axiosConfig.headers ? Object.keys(axiosConfig.headers) : [];
482
+ if (!allHeaders.some((headerKey) => headerKey.toLowerCase() === 'accept')) {
483
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, { accept: '*/*' });
484
+ }
485
+ if (requestObject.json !== false &&
486
+ axiosConfig.data !== undefined &&
487
+ axiosConfig.data !== '' &&
488
+ !(axiosConfig.data instanceof Buffer) &&
489
+ !allHeaders.some((headerKey) => headerKey.toLowerCase() === 'content-type')) {
490
+ axiosConfig.headers = Object.assign(axiosConfig.headers || {}, {
491
+ 'content-type': 'application/json',
492
+ });
493
+ }
494
+ if (requestObject.simple === false) {
495
+ axiosConfig.validateStatus = () => true;
496
+ }
497
+ return axiosConfig;
498
+ }
499
+ async function proxyRequestToAxios(workflow, additionalData, node, uriOrObject, options) {
500
+ let axiosConfig = {
501
+ maxBodyLength: Infinity,
502
+ maxContentLength: Infinity,
503
+ };
504
+ let configObject;
505
+ if (typeof uriOrObject === 'string') {
506
+ configObject = { uri: uriOrObject, ...options };
507
+ }
508
+ else {
509
+ configObject = uriOrObject ?? {};
510
+ }
511
+ axiosConfig = Object.assign(axiosConfig, await parseRequestObject(configObject));
512
+ try {
513
+ const response = await invokeAxios(axiosConfig, configObject.auth);
514
+ let body = response.data;
515
+ if (body instanceof http_1.IncomingMessage && axiosConfig.responseType === 'stream') {
516
+ (0, parse_incoming_message_1.parseIncomingMessage)(body);
517
+ }
518
+ else if (body === '') {
519
+ body = axiosConfig.responseType === 'arraybuffer' ? Buffer.alloc(0) : undefined;
520
+ }
521
+ await additionalData?.hooks?.runHook('nodeFetchedData', [workflow?.id, node]);
522
+ return configObject.resolveWithFullResponse
523
+ ? {
524
+ body,
525
+ headers: { ...response.headers },
526
+ statusCode: response.status,
527
+ statusMessage: response.statusText,
528
+ request: response.request,
529
+ }
530
+ : body;
531
+ }
532
+ catch (error) {
533
+ const { config, response } = error;
534
+ if (error.isAxiosError) {
535
+ error.config = error.request = undefined;
536
+ error.options = (0, pick_1.default)(config ?? {}, ['url', 'method', 'data', 'headers']);
537
+ if (response) {
538
+ di_1.Container.get(logger_1.Logger).debug('Request proxied to Axios failed', { status: response.status });
539
+ let responseData = response.data;
540
+ if (Buffer.isBuffer(responseData) || responseData instanceof stream_1.Readable) {
541
+ responseData = await (0, binary_helper_functions_1.binaryToString)(responseData);
542
+ }
543
+ if (configObject.simple === false) {
544
+ if (configObject.resolveWithFullResponse) {
545
+ return {
546
+ body: responseData,
547
+ headers: response.headers,
548
+ statusCode: response.status,
549
+ statusMessage: response.statusText,
550
+ };
551
+ }
552
+ else {
553
+ return responseData;
554
+ }
555
+ }
556
+ error.message = `${response.status} - ${JSON.stringify(responseData)}`;
557
+ throw Object.assign(error, {
558
+ statusCode: response.status,
559
+ status: response.status,
560
+ error: responseData,
561
+ response: (0, pick_1.default)(response, ['headers', 'status', 'statusText']),
562
+ });
563
+ }
564
+ else if ('rejectUnauthorized' in configObject && error.code?.includes('CERT')) {
565
+ throw new n8n_workflow_1.NodeSslError(error);
566
+ }
567
+ }
568
+ throw error;
569
+ }
570
+ }
571
+ function convertN8nRequestToAxios(n8nRequest) {
572
+ const { headers, method, timeout, auth, proxy, url } = n8nRequest;
573
+ const axiosRequest = {
574
+ headers: headers ?? {},
575
+ method,
576
+ timeout,
577
+ auth,
578
+ proxy,
579
+ url,
580
+ maxBodyLength: Infinity,
581
+ maxContentLength: Infinity,
582
+ };
583
+ axiosRequest.params = n8nRequest.qs;
584
+ if (n8nRequest.abortSignal) {
585
+ axiosRequest.signal = n8nRequest.abortSignal;
586
+ }
587
+ if (n8nRequest.baseURL !== undefined) {
588
+ axiosRequest.baseURL = n8nRequest.baseURL;
589
+ }
590
+ if (n8nRequest.disableFollowRedirect === true) {
591
+ axiosRequest.maxRedirects = 0;
592
+ }
593
+ if (n8nRequest.encoding !== undefined) {
594
+ axiosRequest.responseType = n8nRequest.encoding;
595
+ }
596
+ const host = getHostFromRequestObject(n8nRequest);
597
+ const agentOptions = {};
598
+ if (host) {
599
+ agentOptions.servername = host;
600
+ }
601
+ if (n8nRequest.skipSslCertificateValidation === true) {
602
+ agentOptions.rejectUnauthorized = false;
603
+ }
604
+ axiosRequest.httpsAgent = new https_1.Agent(agentOptions);
605
+ axiosRequest.beforeRedirect = getBeforeRedirectFn(agentOptions, axiosRequest);
606
+ if (n8nRequest.arrayFormat !== undefined) {
607
+ axiosRequest.paramsSerializer = (params) => {
608
+ return (0, qs_1.stringify)(params, { arrayFormat: n8nRequest.arrayFormat });
609
+ };
610
+ }
611
+ const { body } = n8nRequest;
612
+ if (body) {
613
+ const existingContentTypeHeaderKey = searchForHeader(axiosRequest, 'content-type');
614
+ if (existingContentTypeHeaderKey === undefined) {
615
+ axiosRequest.headers = axiosRequest.headers || {};
616
+ if (body instanceof form_data_1.default) {
617
+ axiosRequest.headers = {
618
+ ...axiosRequest.headers,
619
+ ...body.getHeaders(),
620
+ };
621
+ }
622
+ else if (body instanceof url_1.URLSearchParams) {
623
+ axiosRequest.headers['Content-Type'] = 'application/x-www-form-urlencoded';
624
+ }
625
+ }
626
+ else if (axiosRequest.headers?.[existingContentTypeHeaderKey] === 'application/x-www-form-urlencoded') {
627
+ axiosRequest.data = new url_1.URLSearchParams(n8nRequest.body);
628
+ }
629
+ if (typeof body === 'string' || (typeof body === 'object' && !(0, n8n_workflow_1.isObjectEmpty)(body))) {
630
+ axiosRequest.data = body;
631
+ }
632
+ }
633
+ if (n8nRequest.json) {
634
+ const key = searchForHeader(axiosRequest, 'accept');
635
+ if (!key) {
636
+ axiosRequest.headers = {
637
+ ...axiosRequest.headers,
638
+ Accept: 'application/json',
639
+ };
640
+ }
641
+ }
642
+ const userAgentHeader = searchForHeader(axiosRequest, 'user-agent');
643
+ if (!userAgentHeader) {
644
+ axiosRequest.headers = {
645
+ ...axiosRequest.headers,
646
+ 'User-Agent': 'n8n',
647
+ };
648
+ }
649
+ if (n8nRequest.ignoreHttpStatusErrors) {
650
+ axiosRequest.validateStatus = () => true;
651
+ }
652
+ return axiosRequest;
653
+ }
654
+ const NoBodyHttpMethods = ['GET', 'HEAD', 'OPTIONS'];
655
+ const removeEmptyBody = (requestOptions) => {
656
+ const method = requestOptions.method || 'GET';
657
+ if (NoBodyHttpMethods.includes(method) && (0, isEmpty_1.default)(requestOptions.body)) {
658
+ delete requestOptions.body;
659
+ }
660
+ };
661
+ exports.removeEmptyBody = removeEmptyBody;
662
+ async function httpRequest(requestOptions) {
663
+ (0, exports.removeEmptyBody)(requestOptions);
664
+ const axiosRequest = convertN8nRequestToAxios(requestOptions);
665
+ if (axiosRequest.data === undefined ||
666
+ (axiosRequest.method !== undefined && axiosRequest.method.toUpperCase() === 'GET')) {
667
+ delete axiosRequest.data;
668
+ }
669
+ const result = await invokeAxios(axiosRequest, requestOptions.auth);
670
+ if (requestOptions.returnFullResponse) {
671
+ return {
672
+ body: result.data,
673
+ headers: result.headers,
674
+ statusCode: result.status,
675
+ statusMessage: result.statusText,
676
+ };
677
+ }
678
+ return result.data;
679
+ }
680
+ function applyPaginationRequestData(requestData, paginationRequestData) {
681
+ const preparedPaginationData = {
682
+ ...paginationRequestData,
683
+ uri: paginationRequestData.url,
684
+ };
685
+ if ('formData' in requestData) {
686
+ preparedPaginationData.formData = paginationRequestData.body;
687
+ delete preparedPaginationData.body;
688
+ }
689
+ else if ('form' in requestData) {
690
+ preparedPaginationData.form = paginationRequestData.body;
691
+ delete preparedPaginationData.body;
692
+ }
693
+ return (0, merge_1.default)({}, requestData, preparedPaginationData);
694
+ }
695
+ async function requestOAuth2(credentialsType, requestOptions, node, additionalData, oAuth2Options, isN8nRequest = false) {
696
+ (0, exports.removeEmptyBody)(requestOptions);
697
+ const credentials = (await this.getCredentials(credentialsType));
698
+ if (credentials.grantType === 'authorizationCode' && credentials.oauthTokenData === undefined) {
699
+ throw new n8n_workflow_1.ApplicationError('OAuth credentials not connected');
700
+ }
701
+ const oAuthClient = new client_oauth2_1.ClientOAuth2({
702
+ clientId: credentials.clientId,
703
+ clientSecret: credentials.clientSecret,
704
+ accessTokenUri: credentials.accessTokenUrl,
705
+ scopes: credentials.scope.split(' '),
706
+ ignoreSSLIssues: credentials.ignoreSSLIssues,
707
+ authentication: credentials.authentication ?? 'header',
708
+ });
709
+ let oauthTokenData = credentials.oauthTokenData;
710
+ if (credentials.grantType === 'clientCredentials' &&
711
+ (oauthTokenData === undefined ||
712
+ Object.keys(oauthTokenData).length === 0 ||
713
+ oauthTokenData.access_token === '')) {
714
+ const { data } = await oAuthClient.credentials.getToken();
715
+ if (!node.credentials?.[credentialsType]) {
716
+ throw new n8n_workflow_1.ApplicationError('Node does not have credential type', {
717
+ extra: { nodeName: node.name },
718
+ tags: { credentialType: credentialsType },
719
+ });
720
+ }
721
+ const nodeCredentials = node.credentials[credentialsType];
722
+ credentials.oauthTokenData = data;
723
+ await additionalData.credentialsHelper.updateCredentials(nodeCredentials, credentialsType, credentials);
724
+ oauthTokenData = data;
725
+ }
726
+ const accessToken = (0, get_1.default)(oauthTokenData, oAuth2Options?.property) || oauthTokenData.accessToken;
727
+ const refreshToken = oauthTokenData.refreshToken;
728
+ const token = oAuthClient.createToken({
729
+ ...oauthTokenData,
730
+ ...(accessToken ? { access_token: accessToken } : {}),
731
+ ...(refreshToken ? { refresh_token: refreshToken } : {}),
732
+ }, oAuth2Options?.tokenType || oauthTokenData.tokenType);
733
+ requestOptions.rejectUnauthorized = !credentials.ignoreSSLIssues;
734
+ const newRequestOptions = token.sign(requestOptions);
735
+ const newRequestHeaders = (newRequestOptions.headers = newRequestOptions.headers ?? {});
736
+ if (oAuth2Options?.keepBearer === false && typeof newRequestHeaders.Authorization === 'string') {
737
+ newRequestHeaders.Authorization = newRequestHeaders.Authorization.split(' ')[1];
738
+ }
739
+ if (oAuth2Options?.keyToIncludeInAccessTokenHeader) {
740
+ Object.assign(newRequestHeaders, {
741
+ [oAuth2Options.keyToIncludeInAccessTokenHeader]: token.accessToken,
742
+ });
743
+ }
744
+ if (isN8nRequest) {
745
+ return await this.helpers.httpRequest(newRequestOptions).catch(async (error) => {
746
+ if (error.response?.status === 401) {
747
+ this.logger.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" expired. Should revalidate.`);
748
+ const tokenRefreshOptions = {};
749
+ if (oAuth2Options?.includeCredentialsOnRefreshOnBody) {
750
+ const body = {
751
+ client_id: credentials.clientId,
752
+ ...(credentials.grantType === 'authorizationCode' && {
753
+ client_secret: credentials.clientSecret,
754
+ }),
755
+ };
756
+ tokenRefreshOptions.body = body;
757
+ tokenRefreshOptions.headers = {
758
+ Authorization: '',
759
+ };
760
+ }
761
+ let newToken;
762
+ this.logger.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been renewed.`);
763
+ if (credentials.grantType === 'clientCredentials') {
764
+ newToken = await token.client.credentials.getToken();
765
+ }
766
+ else {
767
+ newToken = await token.refresh(tokenRefreshOptions);
768
+ }
769
+ this.logger.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been renewed.`);
770
+ credentials.oauthTokenData = newToken.data;
771
+ if (!node.credentials?.[credentialsType]) {
772
+ throw new n8n_workflow_1.ApplicationError('Node does not have credential type', {
773
+ extra: { nodeName: node.name, credentialType: credentialsType },
774
+ });
775
+ }
776
+ const nodeCredentials = node.credentials[credentialsType];
777
+ await additionalData.credentialsHelper.updateCredentials(nodeCredentials, credentialsType, credentials);
778
+ const refreshedRequestOption = newToken.sign(requestOptions);
779
+ if (oAuth2Options?.keyToIncludeInAccessTokenHeader) {
780
+ Object.assign(newRequestHeaders, {
781
+ [oAuth2Options.keyToIncludeInAccessTokenHeader]: token.accessToken,
782
+ });
783
+ }
784
+ return await this.helpers.httpRequest(refreshedRequestOption);
785
+ }
786
+ throw error;
787
+ });
788
+ }
789
+ const tokenExpiredStatusCode = oAuth2Options?.tokenExpiredStatusCode === undefined
790
+ ? 401
791
+ : oAuth2Options?.tokenExpiredStatusCode;
792
+ return await this.helpers
793
+ .request(newRequestOptions)
794
+ .then((response) => {
795
+ const requestOptions = newRequestOptions;
796
+ if (requestOptions.resolveWithFullResponse === true &&
797
+ requestOptions.simple === false &&
798
+ response.statusCode === tokenExpiredStatusCode) {
799
+ throw response;
800
+ }
801
+ return response;
802
+ })
803
+ .catch(async (error) => {
804
+ if (error.statusCode === tokenExpiredStatusCode) {
805
+ const tokenRefreshOptions = {};
806
+ if (oAuth2Options?.includeCredentialsOnRefreshOnBody) {
807
+ const body = {
808
+ client_id: credentials.clientId,
809
+ client_secret: credentials.clientSecret,
810
+ };
811
+ tokenRefreshOptions.body = body;
812
+ tokenRefreshOptions.headers = {
813
+ Authorization: '',
814
+ };
815
+ }
816
+ this.logger.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" expired. Should revalidate.`);
817
+ let newToken;
818
+ if (credentials.grantType === 'clientCredentials') {
819
+ newToken = await token.client.credentials.getToken();
820
+ }
821
+ else {
822
+ newToken = await token.refresh(tokenRefreshOptions);
823
+ }
824
+ this.logger.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been renewed.`);
825
+ credentials.oauthTokenData = newToken.data;
826
+ if (!node.credentials?.[credentialsType]) {
827
+ throw new n8n_workflow_1.ApplicationError('Node does not have credential type', {
828
+ tags: { credentialType: credentialsType },
829
+ extra: { nodeName: node.name },
830
+ });
831
+ }
832
+ const nodeCredentials = node.credentials[credentialsType];
833
+ await additionalData.credentialsHelper.updateCredentials(nodeCredentials, credentialsType, credentials);
834
+ this.logger.debug(`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been saved to database successfully.`);
835
+ const newRequestOptions = newToken.sign(requestOptions);
836
+ newRequestOptions.headers = newRequestOptions.headers ?? {};
837
+ if (oAuth2Options?.keyToIncludeInAccessTokenHeader) {
838
+ Object.assign(newRequestOptions.headers, {
839
+ [oAuth2Options.keyToIncludeInAccessTokenHeader]: token.accessToken,
840
+ });
841
+ }
842
+ return await this.helpers.request(newRequestOptions);
843
+ }
844
+ throw error;
845
+ });
846
+ }
847
+ async function requestOAuth1(credentialsType, requestOptions, isN8nRequest = false) {
848
+ (0, exports.removeEmptyBody)(requestOptions);
849
+ const credentials = await this.getCredentials(credentialsType);
850
+ if (credentials === undefined) {
851
+ throw new n8n_workflow_1.ApplicationError('No credentials were returned');
852
+ }
853
+ if (credentials.oauthTokenData === undefined) {
854
+ throw new n8n_workflow_1.ApplicationError('OAuth credentials not connected');
855
+ }
856
+ const oauth = new oauth_1_0a_1.default({
857
+ consumer: {
858
+ key: credentials.consumerKey,
859
+ secret: credentials.consumerSecret,
860
+ },
861
+ signature_method: credentials.signatureMethod,
862
+ hash_function(base, key) {
863
+ let algorithm;
864
+ switch (credentials.signatureMethod) {
865
+ case 'HMAC-SHA256':
866
+ algorithm = 'sha256';
867
+ break;
868
+ case 'HMAC-SHA512':
869
+ algorithm = 'sha512';
870
+ break;
871
+ default:
872
+ algorithm = 'sha1';
873
+ break;
874
+ }
875
+ return (0, crypto_1.createHmac)(algorithm, key).update(base).digest('base64');
876
+ },
877
+ });
878
+ const oauthTokenData = credentials.oauthTokenData;
879
+ const token = {
880
+ key: oauthTokenData.oauth_token,
881
+ secret: oauthTokenData.oauth_token_secret,
882
+ };
883
+ requestOptions.data = { ...requestOptions.qs, ...requestOptions.form };
884
+ if ('uri' in requestOptions && !requestOptions.url) {
885
+ requestOptions.url = requestOptions.uri;
886
+ delete requestOptions.uri;
887
+ }
888
+ requestOptions.headers = oauth.toHeader(oauth.authorize(requestOptions, token));
889
+ if (isN8nRequest) {
890
+ return await this.helpers.httpRequest(requestOptions);
891
+ }
892
+ return await this.helpers
893
+ .request(requestOptions)
894
+ .catch(async (error) => {
895
+ throw error;
896
+ });
897
+ }
898
+ async function httpRequestWithAuthentication(credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions) {
899
+ (0, exports.removeEmptyBody)(requestOptions);
900
+ if ('getExecutionCancelSignal' in this) {
901
+ requestOptions.abortSignal = this.getExecutionCancelSignal();
902
+ }
903
+ let credentialsDecrypted;
904
+ try {
905
+ const parentTypes = additionalData.credentialsHelper.getParentTypes(credentialsType);
906
+ if (parentTypes.includes('oAuth1Api')) {
907
+ return await requestOAuth1.call(this, credentialsType, requestOptions, true);
908
+ }
909
+ if (parentTypes.includes('oAuth2Api')) {
910
+ return await requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, additionalCredentialOptions?.oauth2, true);
911
+ }
912
+ if (additionalCredentialOptions?.credentialsDecrypted) {
913
+ credentialsDecrypted = additionalCredentialOptions.credentialsDecrypted.data;
914
+ }
915
+ else {
916
+ credentialsDecrypted =
917
+ await this.getCredentials(credentialsType);
918
+ }
919
+ if (credentialsDecrypted === undefined) {
920
+ throw new n8n_workflow_1.NodeOperationError(node, `Node "${node.name}" does not have any credentials of type "${credentialsType}" set`, { level: 'warning' });
921
+ }
922
+ const data = await additionalData.credentialsHelper.preAuthentication({ helpers: this.helpers }, credentialsDecrypted, credentialsType, node, false);
923
+ if (data) {
924
+ Object.assign(credentialsDecrypted, data);
925
+ }
926
+ requestOptions = await additionalData.credentialsHelper.authenticate(credentialsDecrypted, credentialsType, requestOptions, workflow, node);
927
+ return await httpRequest(requestOptions);
928
+ }
929
+ catch (error) {
930
+ if (error.response?.status === 401 &&
931
+ additionalData.credentialsHelper.preAuthentication !== undefined) {
932
+ try {
933
+ if (credentialsDecrypted !== undefined) {
934
+ const data = await additionalData.credentialsHelper.preAuthentication({ helpers: this.helpers }, credentialsDecrypted, credentialsType, node, true);
935
+ if (data) {
936
+ Object.assign(credentialsDecrypted, data);
937
+ }
938
+ requestOptions = await additionalData.credentialsHelper.authenticate(credentialsDecrypted, credentialsType, requestOptions, workflow, node);
939
+ }
940
+ return await httpRequest(requestOptions);
941
+ }
942
+ catch (error) {
943
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
944
+ }
945
+ }
946
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
947
+ }
948
+ }
949
+ async function requestWithAuthentication(credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions, itemIndex) {
950
+ (0, exports.removeEmptyBody)(requestOptions);
951
+ let credentialsDecrypted;
952
+ try {
953
+ const parentTypes = additionalData.credentialsHelper.getParentTypes(credentialsType);
954
+ if (credentialsType === 'oAuth1Api' || parentTypes.includes('oAuth1Api')) {
955
+ return await requestOAuth1.call(this, credentialsType, requestOptions, false);
956
+ }
957
+ if (credentialsType === 'oAuth2Api' || parentTypes.includes('oAuth2Api')) {
958
+ return await requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, additionalCredentialOptions?.oauth2, false);
959
+ }
960
+ if (additionalCredentialOptions?.credentialsDecrypted) {
961
+ credentialsDecrypted = additionalCredentialOptions.credentialsDecrypted.data;
962
+ }
963
+ else {
964
+ credentialsDecrypted = await this.getCredentials(credentialsType, itemIndex);
965
+ }
966
+ if (credentialsDecrypted === undefined) {
967
+ throw new n8n_workflow_1.NodeOperationError(node, `Node "${node.name}" does not have any credentials of type "${credentialsType}" set`, { level: 'warning' });
968
+ }
969
+ const data = await additionalData.credentialsHelper.preAuthentication({ helpers: this.helpers }, credentialsDecrypted, credentialsType, node, false);
970
+ if (data) {
971
+ Object.assign(credentialsDecrypted, data);
972
+ }
973
+ requestOptions = (await additionalData.credentialsHelper.authenticate(credentialsDecrypted, credentialsType, requestOptions, workflow, node));
974
+ return await proxyRequestToAxios(workflow, additionalData, node, requestOptions);
975
+ }
976
+ catch (error) {
977
+ try {
978
+ if (credentialsDecrypted !== undefined) {
979
+ const data = await additionalData.credentialsHelper.preAuthentication({ helpers: this.helpers }, credentialsDecrypted, credentialsType, node, true);
980
+ if (data) {
981
+ Object.assign(credentialsDecrypted, data);
982
+ requestOptions = (await additionalData.credentialsHelper.authenticate(credentialsDecrypted, credentialsType, requestOptions, workflow, node));
983
+ return await proxyRequestToAxios(workflow, additionalData, node, requestOptions);
984
+ }
985
+ }
986
+ throw error;
987
+ }
988
+ catch (error) {
989
+ if (error instanceof n8n_workflow_1.ExecutionBaseError)
990
+ throw error;
991
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
992
+ }
993
+ }
994
+ }
995
+ const getRequestHelperFunctions = (workflow, node, additionalData, runExecutionData = null, connectionInputData = []) => {
996
+ const getResolvedValue = (parameterValue, itemIndex, runIndex, executeData, additionalKeys, returnObjectAsString = false) => {
997
+ const mode = 'internal';
998
+ if (typeof parameterValue === 'object' ||
999
+ (typeof parameterValue === 'string' && parameterValue.charAt(0) === '=')) {
1000
+ return workflow.expression.getParameterValue(parameterValue, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode, additionalKeys ?? {}, executeData, returnObjectAsString);
1001
+ }
1002
+ return parameterValue;
1003
+ };
1004
+ async function requestWithAuthenticationPaginated(requestOptions, itemIndex, paginationOptions, credentialsType, additionalCredentialOptions) {
1005
+ const responseData = [];
1006
+ if (!requestOptions.qs) {
1007
+ requestOptions.qs = {};
1008
+ }
1009
+ requestOptions.resolveWithFullResponse = true;
1010
+ requestOptions.simple = false;
1011
+ let tempResponseData;
1012
+ let makeAdditionalRequest;
1013
+ let paginateRequestData;
1014
+ const runIndex = 0;
1015
+ const additionalKeys = {
1016
+ $request: requestOptions,
1017
+ $response: {},
1018
+ $version: node.typeVersion,
1019
+ $pageCount: 0,
1020
+ };
1021
+ const executeData = {
1022
+ data: {},
1023
+ node,
1024
+ source: null,
1025
+ };
1026
+ const hashData = {
1027
+ identicalCount: 0,
1028
+ previousLength: 0,
1029
+ previousHash: '',
1030
+ };
1031
+ do {
1032
+ paginateRequestData = getResolvedValue(paginationOptions.request, itemIndex, runIndex, executeData, additionalKeys, false);
1033
+ const tempRequestOptions = applyPaginationRequestData(requestOptions, paginateRequestData);
1034
+ if (!validateUrl(tempRequestOptions.uri)) {
1035
+ throw new n8n_workflow_1.NodeOperationError(node, `'${paginateRequestData.url}' is not a valid URL.`, {
1036
+ itemIndex,
1037
+ runIndex,
1038
+ type: 'invalid_url',
1039
+ });
1040
+ }
1041
+ if (credentialsType) {
1042
+ tempResponseData = await this.helpers.requestWithAuthentication.call(this, credentialsType, tempRequestOptions, additionalCredentialOptions);
1043
+ }
1044
+ else {
1045
+ tempResponseData = await this.helpers.request(tempRequestOptions);
1046
+ }
1047
+ const newResponse = Object.assign({
1048
+ body: {},
1049
+ headers: {},
1050
+ statusCode: 0,
1051
+ }, (0, pick_1.default)(tempResponseData, ['body', 'headers', 'statusCode']));
1052
+ let contentBody;
1053
+ if (newResponse.body instanceof stream_1.Readable && paginationOptions.binaryResult !== true) {
1054
+ contentBody = await (0, binary_helper_functions_1.binaryToString)(newResponse.body);
1055
+ const responseContentType = newResponse.headers['content-type']?.toString() ?? '';
1056
+ if (responseContentType.includes('application/json')) {
1057
+ newResponse.body = (0, n8n_workflow_1.jsonParse)(contentBody, { fallbackValue: {} });
1058
+ }
1059
+ else {
1060
+ newResponse.body = contentBody;
1061
+ }
1062
+ tempResponseData.__bodyResolved = true;
1063
+ tempResponseData.body = newResponse.body;
1064
+ }
1065
+ else {
1066
+ contentBody = newResponse.body;
1067
+ }
1068
+ if (paginationOptions.binaryResult !== true || tempResponseData.headers.etag) {
1069
+ let contentLength = 0;
1070
+ if ('content-length' in tempResponseData.headers) {
1071
+ contentLength = parseInt(tempResponseData.headers['content-length']) || 0;
1072
+ }
1073
+ if (hashData.previousLength === contentLength) {
1074
+ let hash;
1075
+ if (tempResponseData.headers.etag) {
1076
+ hash = tempResponseData.headers.etag;
1077
+ }
1078
+ else {
1079
+ if (typeof contentBody !== 'string') {
1080
+ contentBody = JSON.stringify(contentBody);
1081
+ }
1082
+ hash = crypto_1.default.createHash('md5').update(contentBody).digest('base64');
1083
+ }
1084
+ if (hashData.previousHash === hash) {
1085
+ hashData.identicalCount += 1;
1086
+ if (hashData.identicalCount > 2) {
1087
+ throw new n8n_workflow_1.NodeOperationError(node, 'The returned response was identical 5x, so requests got stopped', {
1088
+ itemIndex,
1089
+ description: 'Check if "Pagination Completed When" has been configured correctly.',
1090
+ });
1091
+ }
1092
+ }
1093
+ else {
1094
+ hashData.identicalCount = 0;
1095
+ }
1096
+ hashData.previousHash = hash;
1097
+ }
1098
+ else {
1099
+ hashData.identicalCount = 0;
1100
+ }
1101
+ hashData.previousLength = contentLength;
1102
+ }
1103
+ responseData.push(tempResponseData);
1104
+ additionalKeys.$response = newResponse;
1105
+ additionalKeys.$pageCount = (additionalKeys.$pageCount ?? 0) + 1;
1106
+ const maxRequests = getResolvedValue(paginationOptions.maxRequests, itemIndex, runIndex, executeData, additionalKeys, false);
1107
+ if (maxRequests && additionalKeys.$pageCount >= maxRequests) {
1108
+ break;
1109
+ }
1110
+ makeAdditionalRequest = getResolvedValue(paginationOptions.continue, itemIndex, runIndex, executeData, additionalKeys, false);
1111
+ if (makeAdditionalRequest) {
1112
+ if (paginationOptions.requestInterval) {
1113
+ const requestInterval = getResolvedValue(paginationOptions.requestInterval, itemIndex, runIndex, executeData, additionalKeys, false);
1114
+ await (0, n8n_workflow_1.sleep)(requestInterval);
1115
+ }
1116
+ if (tempResponseData.statusCode < 200 || tempResponseData.statusCode >= 300) {
1117
+ let data = tempResponseData.body;
1118
+ if (data instanceof stream_1.Readable && paginationOptions.binaryResult !== true) {
1119
+ data = await (0, binary_helper_functions_1.binaryToString)(data);
1120
+ }
1121
+ else if (typeof data === 'object') {
1122
+ data = JSON.stringify(data);
1123
+ }
1124
+ throw Object.assign(new Error(`${tempResponseData.statusCode} - "${data?.toString()}"`), {
1125
+ statusCode: tempResponseData.statusCode,
1126
+ error: data,
1127
+ isAxiosError: true,
1128
+ response: {
1129
+ headers: tempResponseData.headers,
1130
+ status: tempResponseData.statusCode,
1131
+ statusText: tempResponseData.statusMessage,
1132
+ },
1133
+ });
1134
+ }
1135
+ }
1136
+ } while (makeAdditionalRequest);
1137
+ return responseData;
1138
+ }
1139
+ return {
1140
+ httpRequest,
1141
+ requestWithAuthenticationPaginated,
1142
+ async httpRequestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions) {
1143
+ return await httpRequestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions);
1144
+ },
1145
+ request: async (uriOrObject, options) => await proxyRequestToAxios(workflow, additionalData, node, uriOrObject, options),
1146
+ async requestWithAuthentication(credentialsType, requestOptions, additionalCredentialOptions, itemIndex) {
1147
+ return await requestWithAuthentication.call(this, credentialsType, requestOptions, workflow, node, additionalData, additionalCredentialOptions, itemIndex);
1148
+ },
1149
+ async requestOAuth1(credentialsType, requestOptions) {
1150
+ return await requestOAuth1.call(this, credentialsType, requestOptions);
1151
+ },
1152
+ async requestOAuth2(credentialsType, requestOptions, oAuth2Options) {
1153
+ return await requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);
1154
+ },
1155
+ };
1156
+ };
1157
+ exports.getRequestHelperFunctions = getRequestHelperFunctions;
1158
+ //# sourceMappingURL=request-helper-functions.js.map