mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-23 11:44:06 -08:00
⚡ Abstract OAuth signing and make credentials extendable
This commit is contained in:
parent
740cb8a6fc
commit
8228b8505f
|
@ -70,7 +70,7 @@ export interface ICredentialsBase {
|
|||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface ICredentialsDb extends ICredentialsBase, ICredentialsEncrypted{
|
||||
export interface ICredentialsDb extends ICredentialsBase, ICredentialsEncrypted {
|
||||
id: number | string | ObjectID;
|
||||
}
|
||||
|
||||
|
|
|
@ -758,11 +758,7 @@ class App {
|
|||
const findQuery = {} as FindManyOptions;
|
||||
|
||||
// Make sure the variable has an expected value
|
||||
if (req.query.includeData === 'true') {
|
||||
req.query.includeData = true;
|
||||
} else {
|
||||
req.query.includeData = false;
|
||||
}
|
||||
req.query.includeData = (req.query.includeData === 'true' || req.query.includeData === true);
|
||||
|
||||
if (req.query.includeData !== true) {
|
||||
// Return only the fields we need
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
Db,
|
||||
ICredentialsDb,
|
||||
IExecutionDb,
|
||||
IExecutionFlattedDb,
|
||||
IPushDataExecutionFinished,
|
||||
|
@ -13,11 +14,13 @@ import {
|
|||
} from './';
|
||||
|
||||
import {
|
||||
Credentials,
|
||||
UserSettings,
|
||||
WorkflowExecute,
|
||||
} from 'n8n-core';
|
||||
|
||||
import {
|
||||
ICredentialDataDecryptedObject,
|
||||
IDataObject,
|
||||
IExecuteData,
|
||||
IExecuteWorkflowInfo,
|
||||
|
@ -369,6 +372,40 @@ export async function executeWorkflow(workflowInfo: IExecuteWorkflowInfo, additi
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates credentials with new data
|
||||
*
|
||||
* @export
|
||||
* @param {string} name Name of the credentials to update
|
||||
* @param {string} type Type of the credentials to update
|
||||
* @param {ICredentialDataDecryptedObject} data The new credential data
|
||||
* @param {string} encryptionKey The encryption key to use
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function updateCredentials(name: string, type: string, data: ICredentialDataDecryptedObject, encryptionKey: string): Promise<void> {
|
||||
const foundCredentials = await Db.collections.Credentials!.find({ name, type });
|
||||
|
||||
if (!foundCredentials.length) {
|
||||
throw new Error(`Could not find credentials for type "${type}" with name "${name}".`);
|
||||
}
|
||||
|
||||
const credentialsDb = foundCredentials[0];
|
||||
|
||||
// Encrypt the data
|
||||
const credentials = new Credentials(credentialsDb.name, credentialsDb.type, credentialsDb.nodesAccess);
|
||||
credentials.setData(data, encryptionKey);
|
||||
const newCredentialsData = credentials.getDataToSave() as ICredentialsDb;
|
||||
|
||||
// Add special database related data
|
||||
newCredentialsData.updatedAt = this.getCurrentDate();
|
||||
|
||||
// TODO: also add user automatically depending on who is logged in, if anybody is logged in
|
||||
|
||||
// Save the credentials in DB
|
||||
await Db.collections.Credentials!.save(newCredentialsData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the base additional data without webhooks
|
||||
*
|
||||
|
@ -395,6 +432,7 @@ export async function getBase(credentials: IWorkflowCredentials, currentNodePara
|
|||
executeWorkflow,
|
||||
restApiUrl: urlBaseWebhook + config.get('endpoints.rest') as string,
|
||||
timezone,
|
||||
updateCredentials,
|
||||
webhookBaseUrl,
|
||||
webhookTestBaseUrl,
|
||||
currentNodeParameters,
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
"typescript": "~3.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"client-oauth2": "^4.2.5",
|
||||
"cron": "^1.7.2",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"lodash.get": "^4.4.2",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import {
|
||||
IAllExecuteFunctions,
|
||||
IBinaryData,
|
||||
ICredentialType,
|
||||
IDataObject,
|
||||
|
@ -18,6 +19,7 @@ import {
|
|||
} from 'n8n-workflow';
|
||||
|
||||
|
||||
import { OptionsWithUri } from 'request';
|
||||
import * as requestPromise from 'request-promise-native';
|
||||
|
||||
interface Constructable<T> {
|
||||
|
@ -35,6 +37,7 @@ export interface IExecuteFunctions extends IExecuteFunctionsBase {
|
|||
helpers: {
|
||||
prepareBinaryData(binaryData: Buffer, filePath?: string, mimeType?: string): Promise<IBinaryData>;
|
||||
request: requestPromise.RequestPromiseAPI,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any>, // tslint:disable-line:no-any
|
||||
returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[];
|
||||
};
|
||||
}
|
||||
|
@ -44,6 +47,7 @@ export interface IExecuteSingleFunctions extends IExecuteSingleFunctionsBase {
|
|||
helpers: {
|
||||
prepareBinaryData(binaryData: Buffer, filePath?: string, mimeType?: string): Promise<IBinaryData>;
|
||||
request: requestPromise.RequestPromiseAPI,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any>, // tslint:disable-line:no-any
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -52,15 +56,22 @@ export interface IPollFunctions extends IPollFunctionsBase {
|
|||
helpers: {
|
||||
prepareBinaryData(binaryData: Buffer, filePath?: string, mimeType?: string): Promise<IBinaryData>;
|
||||
request: requestPromise.RequestPromiseAPI,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any>, // tslint:disable-line:no-any
|
||||
returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export interface IResponseError extends Error {
|
||||
statusCode?: number;
|
||||
}
|
||||
|
||||
|
||||
export interface ITriggerFunctions extends ITriggerFunctionsBase {
|
||||
helpers: {
|
||||
prepareBinaryData(binaryData: Buffer, filePath?: string, mimeType?: string): Promise<IBinaryData>;
|
||||
request: requestPromise.RequestPromiseAPI,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any>, // tslint:disable-line:no-any
|
||||
returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[];
|
||||
};
|
||||
}
|
||||
|
@ -84,6 +95,7 @@ export interface IUserSettings {
|
|||
export interface ILoadOptionsFunctions extends ILoadOptionsFunctionsBase {
|
||||
helpers: {
|
||||
request?: requestPromise.RequestPromiseAPI,
|
||||
requestOAuth?: (this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions) => Promise<any>, // tslint:disable-line:no-any
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -91,6 +103,7 @@ export interface ILoadOptionsFunctions extends ILoadOptionsFunctionsBase {
|
|||
export interface IHookFunctions extends IHookFunctionsBase {
|
||||
helpers: {
|
||||
request: requestPromise.RequestPromiseAPI,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any>, // tslint:disable-line:no-any
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -99,6 +112,7 @@ export interface IWebhookFunctions extends IWebhookFunctionsBase {
|
|||
helpers: {
|
||||
prepareBinaryData(binaryData: Buffer, filePath?: string, mimeType?: string): Promise<IBinaryData>;
|
||||
request: requestPromise.RequestPromiseAPI,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any>, // tslint:disable-line:no-any
|
||||
returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,11 +2,13 @@ import {
|
|||
Credentials,
|
||||
IHookFunctions,
|
||||
ILoadOptionsFunctions,
|
||||
IResponseError,
|
||||
IWorkflowSettings,
|
||||
BINARY_ENCODING,
|
||||
} from './';
|
||||
|
||||
import {
|
||||
IAllExecuteFunctions,
|
||||
IBinaryData,
|
||||
IContextObject,
|
||||
ICredentialDataDecryptedObject,
|
||||
|
@ -34,9 +36,11 @@ import {
|
|||
WorkflowExecuteMode,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { get } from 'lodash';
|
||||
import * as clientOAuth2 from 'client-oauth2';
|
||||
import { get, unset } from 'lodash';
|
||||
import * as express from "express";
|
||||
import * as path from 'path';
|
||||
import { OptionsWithUri } from 'request';
|
||||
import * as requestPromise from 'request-promise-native';
|
||||
|
||||
import { Magic, MAGIC_MIME_TYPE } from 'mmmagic';
|
||||
|
@ -101,6 +105,70 @@ export async function prepareBinaryData(binaryData: Buffer, filePath?: string, m
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Makes a request using OAuth data for authentication
|
||||
*
|
||||
* @export
|
||||
* @param {IAllExecuteFunctions} this
|
||||
* @param {string} credentialsType
|
||||
* @param {(OptionsWithUri | requestPromise.RequestPromiseOptions)} requestOptions
|
||||
* @param {INode} node
|
||||
* @param {IWorkflowExecuteAdditionalData} additionalData
|
||||
* @returns
|
||||
*/
|
||||
export function requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, node: INode, additionalData: IWorkflowExecuteAdditionalData) {
|
||||
const credentials = this.getCredentials(credentialsType) as ICredentialDataDecryptedObject;
|
||||
|
||||
if (credentials === undefined) {
|
||||
throw new Error('No credentials got returned!');
|
||||
}
|
||||
|
||||
if (credentials.oauthTokenData === undefined) {
|
||||
throw new Error('OAuth credentials not connected!');
|
||||
}
|
||||
|
||||
const oAuthClient = new clientOAuth2({});
|
||||
const oauthTokenData = JSON.parse(credentials.oauthTokenData as string);
|
||||
const token = oAuthClient.createToken(oauthTokenData);
|
||||
|
||||
// Signs the request by adding authorization headers or query parameters depending
|
||||
// on the token-type used.
|
||||
const newRequestOptions = token.sign(requestOptions as clientOAuth2.RequestObject);
|
||||
|
||||
return this.helpers.request!(newRequestOptions)
|
||||
.catch(async (error: IResponseError) => {
|
||||
// TODO: Check if also other codes are possible
|
||||
if (error.statusCode === 401) {
|
||||
// TODO: Whole refresh process is not tested yet
|
||||
// Token is probably not valid anymore. So try refresh it.
|
||||
const newToken = await token.refresh();
|
||||
|
||||
const newCredentialsData = newToken.data;
|
||||
unset(newCredentialsData, 'csrfSecret');
|
||||
unset(newCredentialsData, 'oauthTokenData');
|
||||
|
||||
// Find the name of the credentials
|
||||
if (!node.credentials || !node.credentials[credentialsType]) {
|
||||
throw new Error(`The node "${node.name}" does not have credentials of type "${credentialsType}"!`);
|
||||
}
|
||||
const name = node.credentials[credentialsType];
|
||||
|
||||
// Save the refreshed token
|
||||
await additionalData.updateCredentials(name, credentialsType, newCredentialsData, additionalData.encryptionKey);
|
||||
|
||||
// Make the request again with the new token
|
||||
const newRequestOptions = newToken.sign(requestOptions as clientOAuth2.RequestObject);
|
||||
|
||||
return this.helpers.request!(newRequestOptions);
|
||||
}
|
||||
|
||||
// Unknown error so simply throw it
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Takes generic input data and brings it into the json format n8n uses.
|
||||
*
|
||||
|
@ -355,6 +423,9 @@ export function getExecutePollFunctions(workflow: Workflow, node: INode, additio
|
|||
helpers: {
|
||||
prepareBinaryData,
|
||||
request: requestPromise,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||
},
|
||||
returnJsonArray,
|
||||
},
|
||||
};
|
||||
|
@ -406,6 +477,9 @@ export function getExecuteTriggerFunctions(workflow: Workflow, node: INode, addi
|
|||
helpers: {
|
||||
prepareBinaryData,
|
||||
request: requestPromise,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||
},
|
||||
returnJsonArray,
|
||||
},
|
||||
};
|
||||
|
@ -484,6 +558,9 @@ export function getExecuteFunctions(workflow: Workflow, runExecutionData: IRunEx
|
|||
helpers: {
|
||||
prepareBinaryData,
|
||||
request: requestPromise,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||
},
|
||||
returnJsonArray,
|
||||
},
|
||||
};
|
||||
|
@ -563,6 +640,9 @@ export function getExecuteSingleFunctions(workflow: Workflow, runExecutionData:
|
|||
helpers: {
|
||||
prepareBinaryData,
|
||||
request: requestPromise,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||
},
|
||||
},
|
||||
};
|
||||
})(workflow, runExecutionData, connectionInputData, inputData, node, itemIndex);
|
||||
|
@ -610,6 +690,9 @@ export function getLoadOptionsFunctions(workflow: Workflow, node: INode, additio
|
|||
},
|
||||
helpers: {
|
||||
request: requestPromise,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||
},
|
||||
},
|
||||
};
|
||||
return that;
|
||||
|
@ -665,6 +748,9 @@ export function getExecuteHookFunctions(workflow: Workflow, node: INode, additio
|
|||
},
|
||||
helpers: {
|
||||
request: requestPromise,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||
},
|
||||
},
|
||||
};
|
||||
return that;
|
||||
|
@ -747,6 +833,9 @@ export function getExecuteWebhookFunctions(workflow: Workflow, node: INode, addi
|
|||
helpers: {
|
||||
prepareBinaryData,
|
||||
request: requestPromise,
|
||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||
},
|
||||
returnJsonArray,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { set } from 'lodash';
|
||||
|
||||
import {
|
||||
ICredentialDataDecryptedObject,
|
||||
IExecuteWorkflowInfo,
|
||||
INodeExecutionData,
|
||||
INodeParameters,
|
||||
|
@ -280,6 +281,7 @@ export function WorkflowExecuteAdditionalData(waitPromise: IDeferredPromise<IRun
|
|||
restApiUrl: '',
|
||||
encryptionKey: 'test',
|
||||
timezone: 'America/New_York',
|
||||
updateCredentials: async (name: string, type: string, data: ICredentialDataDecryptedObject, encryptionKey: string): Promise<void> => {},
|
||||
webhookBaseUrl: 'webhook',
|
||||
webhookTestBaseUrl: 'webhook-test',
|
||||
};
|
||||
|
|
|
@ -169,13 +169,21 @@ export default mixins(
|
|||
},
|
||||
methods: {
|
||||
getCredentialTypeData (name: string): ICredentialType | null {
|
||||
for (const credentialData of this.credentialTypes) {
|
||||
if (credentialData.name === name) {
|
||||
return credentialData;
|
||||
}
|
||||
let credentialData = this.$store.getters.credentialType(name);
|
||||
|
||||
if (credentialData === null || credentialData.extends === undefined) {
|
||||
return credentialData;
|
||||
}
|
||||
|
||||
return null;
|
||||
// Credentials extends another one. So get the properties of the one it
|
||||
// extends and add them.
|
||||
credentialData = JSON.parse(JSON.stringify(credentialData));
|
||||
for (const credentialTypeName of credentialData.extends) {
|
||||
const data = this.$store.getters.credentialType(credentialTypeName);
|
||||
credentialData.properties.push.apply(credentialData.properties, data.properties);
|
||||
}
|
||||
|
||||
return credentialData;
|
||||
},
|
||||
credentialsCreated (data: ICredentialsDecryptedResponse): void {
|
||||
this.$emit('credentialsCreated', data);
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import {
|
||||
ICredentialType,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
|
||||
export class GithubOAuth2Api implements ICredentialType {
|
||||
name = 'githubOAuth2Api';
|
||||
// name = 'oAuth2Api/githubOAuth2Api';
|
||||
extends = [
|
||||
'oAuth2Api',
|
||||
];
|
||||
displayName = 'Github OAuth2 API';
|
||||
properties = [
|
||||
];
|
||||
}
|
|
@ -67,6 +67,17 @@ export class HttpRequest implements INodeType {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'oAuth2Api',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
authentication: [
|
||||
'oAuth2',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
properties: [
|
||||
{
|
||||
|
@ -86,6 +97,10 @@ export class HttpRequest implements INodeType {
|
|||
name: 'Header Auth',
|
||||
value: 'headerAuth'
|
||||
},
|
||||
{
|
||||
name: 'OAuth2',
|
||||
value: 'oAuth2'
|
||||
},
|
||||
{
|
||||
name: 'None',
|
||||
value: 'none'
|
||||
|
@ -504,6 +519,7 @@ export class HttpRequest implements INodeType {
|
|||
const httpBasicAuth = this.getCredentials('httpBasicAuth');
|
||||
const httpDigestAuth = this.getCredentials('httpDigestAuth');
|
||||
const httpHeaderAuth = this.getCredentials('httpHeaderAuth');
|
||||
const oAuth2Api = this.getCredentials('oAuth2Api');
|
||||
|
||||
let requestOptions: OptionsWithUri;
|
||||
let setUiParameter: IDataObject;
|
||||
|
@ -658,7 +674,13 @@ export class HttpRequest implements INodeType {
|
|||
}
|
||||
|
||||
// Now that the options are all set make the actual http request
|
||||
const response = await this.helpers.request(requestOptions);
|
||||
let response;
|
||||
|
||||
if (oAuth2Api !== undefined) {
|
||||
response = await this.helpers.requestOAuth.call(this, 'oAuth2Api', requestOptions);
|
||||
} else {
|
||||
response = await this.helpers.request(requestOptions);
|
||||
}
|
||||
|
||||
if (responseFormat === 'file') {
|
||||
const dataPropertyName = this.getNodeParameter('dataPropertyName', 0) as string;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { OptionsWithUri } from 'request';
|
||||
|
||||
import { IExecuteFunctions } from 'n8n-core';
|
||||
import {
|
||||
INodeExecutionData,
|
||||
|
@ -36,11 +38,71 @@ export class OAuth implements INodeType {
|
|||
value: 'get',
|
||||
description: 'Returns the OAuth token data.',
|
||||
},
|
||||
{
|
||||
name: 'Request',
|
||||
value: 'request',
|
||||
description: 'Make an OAuth signed requ.',
|
||||
},
|
||||
],
|
||||
default: 'get',
|
||||
description: 'The operation to perform.',
|
||||
},
|
||||
|
||||
{
|
||||
displayName: 'Request Method',
|
||||
name: 'requestMethod',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'request',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'DELETE',
|
||||
value: 'DELETE'
|
||||
},
|
||||
{
|
||||
name: 'GET',
|
||||
value: 'GET'
|
||||
},
|
||||
{
|
||||
name: 'HEAD',
|
||||
value: 'HEAD'
|
||||
},
|
||||
{
|
||||
name: 'PATCH',
|
||||
value: 'PATCH'
|
||||
},
|
||||
{
|
||||
name: 'POST',
|
||||
value: 'POST'
|
||||
},
|
||||
{
|
||||
name: 'PUT',
|
||||
value: 'PUT'
|
||||
},
|
||||
],
|
||||
default: 'GET',
|
||||
description: 'The request method to use.',
|
||||
},
|
||||
{
|
||||
displayName: 'URL',
|
||||
name: 'url',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'request',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
placeholder: 'http://example.com/index.html',
|
||||
description: 'The URL to make the request to.',
|
||||
required: true,
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
|
@ -62,6 +124,22 @@ export class OAuth implements INodeType {
|
|||
// without knowledge of the node.
|
||||
|
||||
return [this.helpers.returnJsonArray(JSON.parse(credentials.oauthTokenData as string))];
|
||||
} else if (operation === 'request') {
|
||||
const url = this.getNodeParameter('url', 0) as string;
|
||||
const requestMethod = this.getNodeParameter('requestMethod', 0) as string;
|
||||
|
||||
// Authorization Code Grant
|
||||
const requestOptions: OptionsWithUri = {
|
||||
headers: {
|
||||
'User-Agent': 'some-user',
|
||||
},
|
||||
method: requestMethod,
|
||||
uri: url,
|
||||
json: true,
|
||||
};
|
||||
|
||||
const responseData = await this.helpers.requestOAuth.call(this, 'oAuth2Api', requestOptions);
|
||||
return [this.helpers.returnJsonArray(responseData)];
|
||||
} else {
|
||||
throw new Error('Unknown operation');
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
"dist/credentials/FileMaker.credentials.js",
|
||||
"dist/credentials/FlowApi.credentials.js",
|
||||
"dist/credentials/GithubApi.credentials.js",
|
||||
"dist/credentials/GithubOAuth2Api.credentials.js",
|
||||
"dist/credentials/GitlabApi.credentials.js",
|
||||
"dist/credentials/GoogleApi.credentials.js",
|
||||
"dist/credentials/HttpBasicAuth.credentials.js",
|
||||
|
|
|
@ -2,6 +2,8 @@ import { Workflow } from './Workflow';
|
|||
import { WorkflowHooks } from './WorkflowHooks';
|
||||
import * as express from 'express';
|
||||
|
||||
export type IAllExecuteFunctions = IExecuteFunctions | IExecuteSingleFunctions | IHookFunctions | ILoadOptionsFunctions | IPollFunctions | ITriggerFunctions | IWebhookFunctions;
|
||||
|
||||
export interface IBinaryData {
|
||||
[key: string]: string | undefined;
|
||||
data: string;
|
||||
|
@ -58,6 +60,7 @@ export interface ICredentialsEncrypted {
|
|||
export interface ICredentialType {
|
||||
name: string;
|
||||
displayName: string;
|
||||
extends?: string[];
|
||||
properties: INodeProperties[];
|
||||
}
|
||||
|
||||
|
@ -78,7 +81,7 @@ export interface ICredentialData {
|
|||
}
|
||||
|
||||
// The encrypted credentials which the nodes can access
|
||||
export type CredentialInformation = string | number | boolean;
|
||||
export type CredentialInformation = string | number | boolean | IDataObject;
|
||||
|
||||
|
||||
// The encrypted credentials which the nodes can access
|
||||
|
@ -649,6 +652,7 @@ export interface IWorkflowExecuteAdditionalData {
|
|||
httpRequest?: express.Request;
|
||||
restApiUrl: string;
|
||||
timezone: string;
|
||||
updateCredentials: (name: string, type: string, data: ICredentialDataDecryptedObject, encryptionKey: string) => Promise<void>;
|
||||
webhookBaseUrl: string;
|
||||
webhookTestBaseUrl: string;
|
||||
currentNodeParameters? : INodeParameters[];
|
||||
|
|
Loading…
Reference in a new issue