mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
⚡ Make it possible to set credentials to fixed values
This commit is contained in:
parent
8228b8505f
commit
eb285ef711
|
@ -6,6 +6,7 @@ import {
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ActiveExecutions,
|
ActiveExecutions,
|
||||||
|
CredentialsOverwrites,
|
||||||
Db,
|
Db,
|
||||||
GenericHelpers,
|
GenericHelpers,
|
||||||
IWorkflowBase,
|
IWorkflowBase,
|
||||||
|
@ -100,6 +101,10 @@ export class Execute extends Command {
|
||||||
// Wait till the n8n-packages have been read
|
// Wait till the n8n-packages have been read
|
||||||
await loadNodesAndCredentialsPromise;
|
await loadNodesAndCredentialsPromise;
|
||||||
|
|
||||||
|
// Load the credentials overwrites if any exist
|
||||||
|
const credentialsOverwrites = CredentialsOverwrites();
|
||||||
|
await credentialsOverwrites.init();
|
||||||
|
|
||||||
// Add the found types to an instance other parts of the application can use
|
// Add the found types to an instance other parts of the application can use
|
||||||
const nodeTypes = NodeTypes();
|
const nodeTypes = NodeTypes();
|
||||||
await nodeTypes.init(loadNodesAndCredentials.nodeTypes);
|
await nodeTypes.init(loadNodesAndCredentials.nodeTypes);
|
||||||
|
|
|
@ -11,6 +11,7 @@ import * as config from '../config';
|
||||||
import {
|
import {
|
||||||
ActiveWorkflowRunner,
|
ActiveWorkflowRunner,
|
||||||
CredentialTypes,
|
CredentialTypes,
|
||||||
|
CredentialsOverwrites,
|
||||||
Db,
|
Db,
|
||||||
GenericHelpers,
|
GenericHelpers,
|
||||||
LoadNodesAndCredentials,
|
LoadNodesAndCredentials,
|
||||||
|
@ -112,6 +113,10 @@ export class Start extends Command {
|
||||||
const loadNodesAndCredentials = LoadNodesAndCredentials();
|
const loadNodesAndCredentials = LoadNodesAndCredentials();
|
||||||
await loadNodesAndCredentials.init();
|
await loadNodesAndCredentials.init();
|
||||||
|
|
||||||
|
// Load the credentials overwrites if any exist
|
||||||
|
const credentialsOverwrites = CredentialsOverwrites();
|
||||||
|
await credentialsOverwrites.init();
|
||||||
|
|
||||||
// Add the found types to an instance other parts of the application can use
|
// Add the found types to an instance other parts of the application can use
|
||||||
const nodeTypes = NodeTypes();
|
const nodeTypes = NodeTypes();
|
||||||
await nodeTypes.init(loadNodesAndCredentials.nodeTypes);
|
await nodeTypes.init(loadNodesAndCredentials.nodeTypes);
|
||||||
|
|
|
@ -54,6 +54,19 @@ const config = convict({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
credentials: {
|
||||||
|
overwrite: {
|
||||||
|
// Allows to set default values for credentials which
|
||||||
|
// get automatically prefilled and the user does not get
|
||||||
|
// displayed and can not change.
|
||||||
|
// Format: { CREDENTIAL_NAME: { PARAMTER: VALUE }}
|
||||||
|
doc: 'Overwrites for credentials',
|
||||||
|
format: '*',
|
||||||
|
default: '{}',
|
||||||
|
env: 'CREDENTIALS_OVERWRITE'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
executions: {
|
executions: {
|
||||||
// If a workflow executes all the data gets saved by default. This
|
// If a workflow executes all the data gets saved by default. This
|
||||||
// could be a problem when a workflow gets executed a lot and processes
|
// could be a problem when a workflow gets executed a lot and processes
|
||||||
|
|
|
@ -3,6 +3,9 @@ import {
|
||||||
ICredentialTypes as ICredentialTypesInterface,
|
ICredentialTypes as ICredentialTypesInterface,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CredentialsOverwrites,
|
||||||
|
} from './';
|
||||||
|
|
||||||
class CredentialTypesClass implements ICredentialTypesInterface {
|
class CredentialTypesClass implements ICredentialTypesInterface {
|
||||||
|
|
||||||
|
@ -13,6 +16,19 @@ class CredentialTypesClass implements ICredentialTypesInterface {
|
||||||
|
|
||||||
async init(credentialTypes: { [key: string]: ICredentialType }): Promise<void> {
|
async init(credentialTypes: { [key: string]: ICredentialType }): Promise<void> {
|
||||||
this.credentialTypes = credentialTypes;
|
this.credentialTypes = credentialTypes;
|
||||||
|
|
||||||
|
// Load the credentials overwrites if any exist
|
||||||
|
const credentialsOverwrites = CredentialsOverwrites().getAll();
|
||||||
|
|
||||||
|
for (const credentialType of Object.keys(credentialsOverwrites)) {
|
||||||
|
if (credentialTypes[credentialType] === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add which properties got overwritten that the Editor-UI knows
|
||||||
|
// which properties it should hide
|
||||||
|
credentialTypes[credentialType].__overwrittenProperties = Object.keys(credentialsOverwrites[credentialType]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAll(): ICredentialType[] {
|
getAll(): ICredentialType[] {
|
||||||
|
|
81
packages/cli/src/CredentialsHelper.ts
Normal file
81
packages/cli/src/CredentialsHelper.ts
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import {
|
||||||
|
Credentials,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ICredentialDataDecryptedObject,
|
||||||
|
ICredentialsHelper,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CredentialsOverwrites,
|
||||||
|
Db,
|
||||||
|
ICredentialsDb,
|
||||||
|
} from './';
|
||||||
|
|
||||||
|
|
||||||
|
export class CredentialsHelper extends ICredentialsHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the credentials instance
|
||||||
|
*
|
||||||
|
* @param {string} name Name of the credentials to return instance of
|
||||||
|
* @param {string} type Type of the credentials to return instance of
|
||||||
|
* @returns {Credentials}
|
||||||
|
* @memberof CredentialsHelper
|
||||||
|
*/
|
||||||
|
getCredentials(name: string, type: string): Credentials {
|
||||||
|
if (!this.workflowCredentials[type]) {
|
||||||
|
throw new Error(`No credentials of type "${type}" exist.`);
|
||||||
|
}
|
||||||
|
if (!this.workflowCredentials[type][name]) {
|
||||||
|
throw new Error(`No credentials with name "${name}" exist for type "${type}".`);
|
||||||
|
}
|
||||||
|
const credentialData = this.workflowCredentials[type][name];
|
||||||
|
|
||||||
|
return new Credentials(credentialData.name, credentialData.type, credentialData.nodesAccess, credentialData.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the decrypted credential data with applied overwrites
|
||||||
|
*
|
||||||
|
* @param {string} name Name of the credentials to return data of
|
||||||
|
* @param {string} type Type of the credentials to return data of
|
||||||
|
* @returns {ICredentialDataDecryptedObject}
|
||||||
|
* @memberof CredentialsHelper
|
||||||
|
*/
|
||||||
|
getDecrypted(name: string, type: string): ICredentialDataDecryptedObject {
|
||||||
|
const credentials = this.getCredentials(name, type);
|
||||||
|
|
||||||
|
// Load and apply the credentials overwrites if any exist
|
||||||
|
const credentialsOverwrites = CredentialsOverwrites();
|
||||||
|
return credentialsOverwrites.applyOverwrite(credentials.type, credentials.getData(this.encryptionKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates credentials in the database
|
||||||
|
*
|
||||||
|
* @param {string} name Name of the credentials to set data of
|
||||||
|
* @param {string} type Type of the credentials to set data of
|
||||||
|
* @param {ICredentialDataDecryptedObject} data The data to set
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
* @memberof CredentialsHelper
|
||||||
|
*/
|
||||||
|
async updateCredentials(name: string, type: string, data: ICredentialDataDecryptedObject): Promise<void> {
|
||||||
|
const credentials = await this.getCredentials(name, type);
|
||||||
|
|
||||||
|
credentials.setData(data, this.encryptionKey);
|
||||||
|
const newCredentialsData = credentials.getDataToSave() as ICredentialsDb;
|
||||||
|
|
||||||
|
// Add special database related data
|
||||||
|
newCredentialsData.updatedAt = new Date();
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
56
packages/cli/src/CredentialsOverwrites.ts
Normal file
56
packages/cli/src/CredentialsOverwrites.ts
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import {
|
||||||
|
ICredentialDataDecryptedObject,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ICredentialsOverwrite,
|
||||||
|
GenericHelpers,
|
||||||
|
} from './';
|
||||||
|
|
||||||
|
|
||||||
|
class CredentialsOverwritesClass {
|
||||||
|
|
||||||
|
private overwriteData: ICredentialsOverwrite = {};
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
const data = await GenericHelpers.getConfigValue('credentials.overwrite') as string;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.overwriteData = JSON.parse(data);
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`The credentials-overwrite is not valid JSON.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyOverwrite(type: string, data: ICredentialDataDecryptedObject) {
|
||||||
|
const overwrites = this.get(type);
|
||||||
|
|
||||||
|
if (overwrites === undefined) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const returnData = JSON.parse(JSON.stringify(data));
|
||||||
|
Object.assign(returnData, overwrites);
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
|
|
||||||
|
get(type: string): ICredentialDataDecryptedObject | undefined {
|
||||||
|
return this.overwriteData[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
getAll(): ICredentialsOverwrite {
|
||||||
|
return this.overwriteData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let credentialsOverwritesInstance: CredentialsOverwritesClass | undefined;
|
||||||
|
|
||||||
|
export function CredentialsOverwrites(): CredentialsOverwritesClass {
|
||||||
|
if (credentialsOverwritesInstance === undefined) {
|
||||||
|
credentialsOverwritesInstance = new CredentialsOverwritesClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentialsOverwritesInstance;
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
ICredentialDataDecryptedObject,
|
||||||
ICredentialsDecrypted,
|
ICredentialsDecrypted,
|
||||||
ICredentialsEncrypted,
|
ICredentialsEncrypted,
|
||||||
IDataObject,
|
IDataObject,
|
||||||
|
@ -34,6 +35,9 @@ export interface ICustomRequest extends Request {
|
||||||
parsedUrl: Url | undefined;
|
parsedUrl: Url | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ICredentialsOverwrite {
|
||||||
|
[key: string]: ICredentialDataDecryptedObject;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IDatabaseCollections {
|
export interface IDatabaseCollections {
|
||||||
Credentials: Repository<ICredentialsDb> | null;
|
Credentials: Repository<ICredentialsDb> | null;
|
||||||
|
|
|
@ -137,7 +137,7 @@ class LoadNodesAndCredentialsClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.credentialTypes[credentialName] = tempCredential;
|
this.credentialTypes[tempCredential.name] = tempCredential;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class NodeTypesClass implements INodeTypes {
|
||||||
// Some nodeTypes need to get special parameters applied like the
|
// Some nodeTypes need to get special parameters applied like the
|
||||||
// polling nodes the polling times
|
// polling nodes the polling times
|
||||||
for (const nodeTypeData of Object.values(nodeTypes)) {
|
for (const nodeTypeData of Object.values(nodeTypes)) {
|
||||||
const applyParameters = NodeHelpers.getSpecialNodeParameters(nodeTypeData.type)
|
const applyParameters = NodeHelpers.getSpecialNodeParameters(nodeTypeData.type);
|
||||||
|
|
||||||
if (applyParameters.length) {
|
if (applyParameters.length) {
|
||||||
nodeTypeData.type.description.properties.unshift.apply(nodeTypeData.type.description.properties, applyParameters);
|
nodeTypeData.type.description.properties.unshift.apply(nodeTypeData.type.description.properties, applyParameters);
|
||||||
|
|
|
@ -18,6 +18,7 @@ import * as csrf from 'csrf';
|
||||||
import {
|
import {
|
||||||
ActiveExecutions,
|
ActiveExecutions,
|
||||||
ActiveWorkflowRunner,
|
ActiveWorkflowRunner,
|
||||||
|
CredentialsOverwrites,
|
||||||
CredentialTypes,
|
CredentialTypes,
|
||||||
Db,
|
Db,
|
||||||
IActivationError,
|
IActivationError,
|
||||||
|
@ -648,6 +649,10 @@ class App {
|
||||||
this.app.post('/rest/credentials', ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<ICredentialsResponse> => {
|
this.app.post('/rest/credentials', ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<ICredentialsResponse> => {
|
||||||
const incomingData = req.body;
|
const incomingData = req.body;
|
||||||
|
|
||||||
|
if (!incomingData.name || incomingData.name.length < 3) {
|
||||||
|
throw new ResponseHelper.ResponseError(`Credentials name must be at least 3 characters long.`, undefined, 400);
|
||||||
|
}
|
||||||
|
|
||||||
// Add the added date for node access permissions
|
// Add the added date for node access permissions
|
||||||
for (const nodeAccess of incomingData.nodesAccess) {
|
for (const nodeAccess of incomingData.nodesAccess) {
|
||||||
nodeAccess.date = this.getCurrentDate();
|
nodeAccess.date = this.getCurrentDate();
|
||||||
|
@ -684,6 +689,7 @@ class App {
|
||||||
|
|
||||||
// Save the credentials in DB
|
// Save the credentials in DB
|
||||||
const result = await Db.collections.Credentials!.save(newCredentialsData);
|
const result = await Db.collections.Credentials!.save(newCredentialsData);
|
||||||
|
result.data = incomingData.data;
|
||||||
|
|
||||||
// Convert to response format in which the id is a string
|
// Convert to response format in which the id is a string
|
||||||
(result as unknown as ICredentialsResponse).id = result.id.toString();
|
(result as unknown as ICredentialsResponse).id = result.id.toString();
|
||||||
|
@ -805,14 +811,6 @@ class App {
|
||||||
|
|
||||||
const results = await Db.collections.Credentials!.find(findQuery) as unknown as ICredentialsResponse[];
|
const results = await Db.collections.Credentials!.find(findQuery) as unknown as ICredentialsResponse[];
|
||||||
|
|
||||||
let encryptionKey = undefined;
|
|
||||||
if (req.query.includeData === true) {
|
|
||||||
encryptionKey = await UserSettings.getEncryptionKey();
|
|
||||||
if (encryptionKey === undefined) {
|
|
||||||
throw new Error('No encryption key got found to decrypt the credentials!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let result;
|
let result;
|
||||||
for (result of results) {
|
for (result of results) {
|
||||||
(result as ICredentialsDecryptedResponse).id = result.id.toString();
|
(result as ICredentialsDecryptedResponse).id = result.id.toString();
|
||||||
|
@ -866,19 +864,17 @@ class App {
|
||||||
}
|
}
|
||||||
|
|
||||||
const credentials = new Credentials(result.name, result.type, result.nodesAccess, result.data);
|
const credentials = new Credentials(result.name, result.type, result.nodesAccess, result.data);
|
||||||
(result as ICredentialsDecryptedDb).data = credentials.getData(encryptionKey!);
|
const savedCredentialsData = credentials.getData(encryptionKey);
|
||||||
(result as ICredentialsDecryptedResponse).id = result.id.toString();
|
|
||||||
|
|
||||||
const oauthCredentials = (result as ICredentialsDecryptedDb).data;
|
// Load the credentials overwrites if any exist
|
||||||
if (oauthCredentials === undefined) {
|
const credentialsOverwrites = CredentialsOverwrites();
|
||||||
throw new Error('Unable to read OAuth credentials');
|
const oauthCredentials = credentialsOverwrites.applyOverwrite(credentials.type, savedCredentialsData);
|
||||||
}
|
|
||||||
|
|
||||||
const token = new csrf();
|
const token = new csrf();
|
||||||
// Generate a CSRF prevention token and send it as a OAuth2 state stringma/ERR
|
// Generate a CSRF prevention token and send it as a OAuth2 state stringma/ERR
|
||||||
oauthCredentials.csrfSecret = token.secretSync();
|
const csrfSecret = token.secretSync();
|
||||||
const state = {
|
const state = {
|
||||||
token: token.create(oauthCredentials.csrfSecret),
|
token: token.create(csrfSecret),
|
||||||
cid: req.query.id
|
cid: req.query.id
|
||||||
};
|
};
|
||||||
const stateEncodedStr = Buffer.from(JSON.stringify(state)).toString('base64') as string;
|
const stateEncodedStr = Buffer.from(JSON.stringify(state)).toString('base64') as string;
|
||||||
|
@ -893,7 +889,8 @@ class App {
|
||||||
state: stateEncodedStr,
|
state: stateEncodedStr,
|
||||||
});
|
});
|
||||||
|
|
||||||
credentials.setData(oauthCredentials, encryptionKey);
|
savedCredentialsData.csrfSecret = csrfSecret;
|
||||||
|
credentials.setData(savedCredentialsData, encryptionKey);
|
||||||
const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb;
|
const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb;
|
||||||
|
|
||||||
// Add special database related data
|
// Add special database related data
|
||||||
|
@ -939,12 +936,11 @@ class App {
|
||||||
}
|
}
|
||||||
|
|
||||||
const credentials = new Credentials(result.name, result.type, result.nodesAccess, result.data);
|
const credentials = new Credentials(result.name, result.type, result.nodesAccess, result.data);
|
||||||
(result as ICredentialsDecryptedDb).data = credentials.getData(encryptionKey!);
|
const savedCredentialsData = credentials.getData(encryptionKey!);
|
||||||
const oauthCredentials = (result as ICredentialsDecryptedDb).data;
|
|
||||||
if (oauthCredentials === undefined) {
|
// Load the credentials overwrites if any exist
|
||||||
const errorResponse = new ResponseHelper.ResponseError('Unable to read OAuth credentials!', undefined, 503);
|
const credentialsOverwrites = CredentialsOverwrites();
|
||||||
return ResponseHelper.sendErrorResponse(res, errorResponse);
|
const oauthCredentials = credentialsOverwrites.applyOverwrite(credentials.type, savedCredentialsData);
|
||||||
}
|
|
||||||
|
|
||||||
const token = new csrf();
|
const token = new csrf();
|
||||||
if (oauthCredentials.csrfSecret === undefined || !token.verify(oauthCredentials.csrfSecret as string, state.token)) {
|
if (oauthCredentials.csrfSecret === undefined || !token.verify(oauthCredentials.csrfSecret as string, state.token)) {
|
||||||
|
@ -968,9 +964,10 @@ class App {
|
||||||
return ResponseHelper.sendErrorResponse(res, errorResponse);
|
return ResponseHelper.sendErrorResponse(res, errorResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
oauthCredentials.oauthTokenData = JSON.stringify(oauthToken.data);
|
savedCredentialsData.oauthTokenData = JSON.stringify(oauthToken.data);
|
||||||
_.unset(oauthCredentials, 'csrfSecret');
|
_.unset(savedCredentialsData, 'csrfSecret');
|
||||||
credentials.setData(oauthCredentials, encryptionKey);
|
|
||||||
|
credentials.setData(savedCredentialsData, encryptionKey);
|
||||||
const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb;
|
const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb;
|
||||||
// Add special database related data
|
// Add special database related data
|
||||||
newCredentialsData.updatedAt = this.getCurrentDate();
|
newCredentialsData.updatedAt = this.getCurrentDate();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {
|
import {
|
||||||
|
CredentialsHelper,
|
||||||
Db,
|
Db,
|
||||||
ICredentialsDb,
|
|
||||||
IExecutionDb,
|
IExecutionDb,
|
||||||
IExecutionFlattedDb,
|
IExecutionFlattedDb,
|
||||||
IPushDataExecutionFinished,
|
IPushDataExecutionFinished,
|
||||||
|
@ -14,13 +14,11 @@ import {
|
||||||
} from './';
|
} from './';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Credentials,
|
|
||||||
UserSettings,
|
UserSettings,
|
||||||
WorkflowExecute,
|
WorkflowExecute,
|
||||||
} from 'n8n-core';
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ICredentialDataDecryptedObject,
|
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IExecuteData,
|
IExecuteData,
|
||||||
IExecuteWorkflowInfo,
|
IExecuteWorkflowInfo,
|
||||||
|
@ -372,40 +370,6 @@ 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
|
* Returns the base additional data without webhooks
|
||||||
*
|
*
|
||||||
|
@ -428,11 +392,11 @@ export async function getBase(credentials: IWorkflowCredentials, currentNodePara
|
||||||
|
|
||||||
return {
|
return {
|
||||||
credentials,
|
credentials,
|
||||||
|
credentialsHelper: new CredentialsHelper(credentials, encryptionKey),
|
||||||
encryptionKey,
|
encryptionKey,
|
||||||
executeWorkflow,
|
executeWorkflow,
|
||||||
restApiUrl: urlBaseWebhook + config.get('endpoints.rest') as string,
|
restApiUrl: urlBaseWebhook + config.get('endpoints.rest') as string,
|
||||||
timezone,
|
timezone,
|
||||||
updateCredentials,
|
|
||||||
webhookBaseUrl,
|
webhookBaseUrl,
|
||||||
webhookTestBaseUrl,
|
webhookTestBaseUrl,
|
||||||
currentNodeParameters,
|
currentNodeParameters,
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
export * from './CredentialsHelper';
|
||||||
export * from './CredentialTypes';
|
export * from './CredentialTypes';
|
||||||
|
export * from './CredentialsOverwrites';
|
||||||
export * from './Interfaces';
|
export * from './Interfaces';
|
||||||
export * from './LoadNodesAndCredentials';
|
export * from './LoadNodesAndCredentials';
|
||||||
export * from './NodeTypes';
|
export * from './NodeTypes';
|
||||||
|
|
|
@ -1,25 +1,14 @@
|
||||||
import {
|
import {
|
||||||
ICredentialDataDecryptedObject,
|
|
||||||
CredentialInformation,
|
CredentialInformation,
|
||||||
|
ICredentialDataDecryptedObject,
|
||||||
|
ICredentials,
|
||||||
ICredentialsEncrypted,
|
ICredentialsEncrypted,
|
||||||
ICredentialNodeAccess,
|
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import { enc, AES } from 'crypto-js';
|
import { enc, AES } from 'crypto-js';
|
||||||
|
|
||||||
export class Credentials implements ICredentialsEncrypted {
|
|
||||||
name: string;
|
|
||||||
type: string;
|
|
||||||
data: string | undefined;
|
|
||||||
nodesAccess: ICredentialNodeAccess[];
|
|
||||||
|
|
||||||
|
export class Credentials extends ICredentials {
|
||||||
constructor(name: string, type: string, nodesAccess: ICredentialNodeAccess[], data?: string) {
|
|
||||||
this.name = name;
|
|
||||||
this.type = type;
|
|
||||||
this.nodesAccess = nodesAccess;
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import {
|
import {
|
||||||
Credentials,
|
|
||||||
IHookFunctions,
|
IHookFunctions,
|
||||||
ILoadOptionsFunctions,
|
ILoadOptionsFunctions,
|
||||||
IResponseError,
|
IResponseError,
|
||||||
|
@ -154,7 +153,7 @@ export function requestOAuth(this: IAllExecuteFunctions, credentialsType: string
|
||||||
const name = node.credentials[credentialsType];
|
const name = node.credentials[credentialsType];
|
||||||
|
|
||||||
// Save the refreshed token
|
// Save the refreshed token
|
||||||
await additionalData.updateCredentials(name, credentialsType, newCredentialsData, additionalData.encryptionKey);
|
await additionalData.credentialsHelper.updateCredentials(name, credentialsType, newCredentialsData);
|
||||||
|
|
||||||
// Make the request again with the new token
|
// Make the request again with the new token
|
||||||
const newRequestOptions = newToken.sign(requestOptions as clientOAuth2.RequestObject);
|
const newRequestOptions = newToken.sign(requestOptions as clientOAuth2.RequestObject);
|
||||||
|
@ -244,20 +243,7 @@ export function getCredentials(workflow: Workflow, node: INode, type: string, ad
|
||||||
|
|
||||||
const name = node.credentials[type];
|
const name = node.credentials[type];
|
||||||
|
|
||||||
if (!additionalData.credentials[type]) {
|
const decryptedDataObject = additionalData.credentialsHelper.getDecrypted(name, type);
|
||||||
throw new Error(`No credentials of type "${type}" exist.`);
|
|
||||||
}
|
|
||||||
if (!additionalData.credentials[type][name]) {
|
|
||||||
throw new Error(`No credentials with name "${name}" exist for type "${type}".`);
|
|
||||||
}
|
|
||||||
const credentialData = additionalData.credentials[type][name];
|
|
||||||
|
|
||||||
const credentials = new Credentials(name, type, credentialData.nodesAccess, credentialData.data);
|
|
||||||
const decryptedDataObject = credentials.getData(additionalData.encryptionKey, node.type);
|
|
||||||
|
|
||||||
if (decryptedDataObject === null) {
|
|
||||||
throw new Error('Could not get the credentials');
|
|
||||||
}
|
|
||||||
|
|
||||||
return decryptedDataObject;
|
return decryptedDataObject;
|
||||||
}
|
}
|
||||||
|
@ -423,7 +409,7 @@ export function getExecutePollFunctions(workflow: Workflow, node: INode, additio
|
||||||
helpers: {
|
helpers: {
|
||||||
prepareBinaryData,
|
prepareBinaryData,
|
||||||
request: requestPromise,
|
request: requestPromise,
|
||||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
|
||||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||||
},
|
},
|
||||||
returnJsonArray,
|
returnJsonArray,
|
||||||
|
@ -477,7 +463,7 @@ export function getExecuteTriggerFunctions(workflow: Workflow, node: INode, addi
|
||||||
helpers: {
|
helpers: {
|
||||||
prepareBinaryData,
|
prepareBinaryData,
|
||||||
request: requestPromise,
|
request: requestPromise,
|
||||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
|
||||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||||
},
|
},
|
||||||
returnJsonArray,
|
returnJsonArray,
|
||||||
|
@ -558,7 +544,7 @@ export function getExecuteFunctions(workflow: Workflow, runExecutionData: IRunEx
|
||||||
helpers: {
|
helpers: {
|
||||||
prepareBinaryData,
|
prepareBinaryData,
|
||||||
request: requestPromise,
|
request: requestPromise,
|
||||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
|
||||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||||
},
|
},
|
||||||
returnJsonArray,
|
returnJsonArray,
|
||||||
|
@ -640,7 +626,7 @@ export function getExecuteSingleFunctions(workflow: Workflow, runExecutionData:
|
||||||
helpers: {
|
helpers: {
|
||||||
prepareBinaryData,
|
prepareBinaryData,
|
||||||
request: requestPromise,
|
request: requestPromise,
|
||||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
|
||||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -690,7 +676,7 @@ export function getLoadOptionsFunctions(workflow: Workflow, node: INode, additio
|
||||||
},
|
},
|
||||||
helpers: {
|
helpers: {
|
||||||
request: requestPromise,
|
request: requestPromise,
|
||||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
|
||||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -748,7 +734,7 @@ export function getExecuteHookFunctions(workflow: Workflow, node: INode, additio
|
||||||
},
|
},
|
||||||
helpers: {
|
helpers: {
|
||||||
request: requestPromise,
|
request: requestPromise,
|
||||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
|
||||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -833,7 +819,7 @@ export function getExecuteWebhookFunctions(workflow: Workflow, node: INode, addi
|
||||||
helpers: {
|
helpers: {
|
||||||
prepareBinaryData,
|
prepareBinaryData,
|
||||||
request: requestPromise,
|
request: requestPromise,
|
||||||
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> {
|
requestOAuth(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions): Promise<any> { // tslint:disable-line:no-any
|
||||||
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
return requestOAuth.call(this, credentialsType, requestOptions, node, additionalData);
|
||||||
},
|
},
|
||||||
returnJsonArray,
|
returnJsonArray,
|
||||||
|
|
|
@ -143,7 +143,6 @@ export async function writeUserSettings(userSettings: IUserSettings, settingsPat
|
||||||
*/
|
*/
|
||||||
export async function getUserSettings(settingsPath?: string, ignoreCache?: boolean): Promise<IUserSettings | undefined> {
|
export async function getUserSettings(settingsPath?: string, ignoreCache?: boolean): Promise<IUserSettings | undefined> {
|
||||||
if (settingsCache !== undefined && ignoreCache !== true) {
|
if (settingsCache !== undefined && ignoreCache !== true) {
|
||||||
|
|
||||||
return settingsCache;
|
return settingsCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { set } from 'lodash';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ICredentialDataDecryptedObject,
|
ICredentialDataDecryptedObject,
|
||||||
|
ICredentialsHelper,
|
||||||
IExecuteWorkflowInfo,
|
IExecuteWorkflowInfo,
|
||||||
INodeExecutionData,
|
INodeExecutionData,
|
||||||
INodeParameters,
|
INodeParameters,
|
||||||
|
@ -16,11 +17,25 @@ import {
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
Credentials,
|
||||||
IDeferredPromise,
|
IDeferredPromise,
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
} from '../src';
|
} from '../src';
|
||||||
|
|
||||||
|
|
||||||
|
export class CredentialsHelper extends ICredentialsHelper {
|
||||||
|
getDecrypted(name: string, type: string): ICredentialDataDecryptedObject {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
getCredentials(name: string, type: string): Credentials {
|
||||||
|
return new Credentials('', '', [], '');
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateCredentials(name: string, type: string, data: ICredentialDataDecryptedObject): Promise<void> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class NodeTypesClass implements INodeTypes {
|
class NodeTypesClass implements INodeTypes {
|
||||||
|
|
||||||
nodeTypes: INodeTypeData = {
|
nodeTypes: INodeTypeData = {
|
||||||
|
@ -276,12 +291,12 @@ export function WorkflowExecuteAdditionalData(waitPromise: IDeferredPromise<IRun
|
||||||
|
|
||||||
return {
|
return {
|
||||||
credentials: {},
|
credentials: {},
|
||||||
|
credentialsHelper: new CredentialsHelper({}, ''),
|
||||||
hooks: new WorkflowHooks(hookFunctions, 'trigger', '1', workflowData),
|
hooks: new WorkflowHooks(hookFunctions, 'trigger', '1', workflowData),
|
||||||
executeWorkflow: async (workflowInfo: IExecuteWorkflowInfo): Promise<any> => {}, // tslint:disable-line:no-any
|
executeWorkflow: async (workflowInfo: IExecuteWorkflowInfo): Promise<any> => {}, // tslint:disable-line:no-any
|
||||||
restApiUrl: '',
|
restApiUrl: '',
|
||||||
encryptionKey: 'test',
|
encryptionKey: 'test',
|
||||||
timezone: 'America/New_York',
|
timezone: 'America/New_York',
|
||||||
updateCredentials: async (name: string, type: string, data: ICredentialDataDecryptedObject, encryptionKey: string): Promise<void> => {},
|
|
||||||
webhookBaseUrl: 'webhook',
|
webhookBaseUrl: 'webhook',
|
||||||
webhookTestBaseUrl: 'webhook-test',
|
webhookTestBaseUrl: 'webhook-test',
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
Credential type:
|
Credential type:
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="18">
|
<el-col :span="18">
|
||||||
<el-select v-model="credentialType" placeholder="Select Type" size="small">
|
<el-select v-model="credentialType" filterable placeholder="Select Type" size="small">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in credentialTypes"
|
v-for="item in credentialTypes"
|
||||||
:key="item.name"
|
:key="item.name"
|
||||||
|
|
|
@ -34,14 +34,14 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<div class="headline">
|
<div class="headline" v-if="credentialProperties.length">
|
||||||
Credential Data:
|
Credential Data:
|
||||||
<el-tooltip class="credentials-info" placement="top" effect="light">
|
<el-tooltip class="credentials-info" placement="top" effect="light">
|
||||||
<div slot="content" v-html="helpTexts.credentialsData"></div>
|
<div slot="content" v-html="helpTexts.credentialsData"></div>
|
||||||
<font-awesome-icon icon="question-circle" />
|
<font-awesome-icon icon="question-circle" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<el-row v-for="parameter in credentialTypeData.properties" :key="parameter.name" class="parameter-wrapper">
|
<el-row v-for="parameter in credentialProperties" :key="parameter.name" class="parameter-wrapper">
|
||||||
<el-col :span="6" class="parameter-name">
|
<el-col :span="6" class="parameter-name">
|
||||||
{{parameter.displayName}}:
|
{{parameter.displayName}}:
|
||||||
<el-tooltip placement="top" class="parameter-info" v-if="parameter.description" effect="light">
|
<el-tooltip placement="top" class="parameter-info" v-if="parameter.description" effect="light">
|
||||||
|
@ -97,7 +97,11 @@ import { restApi } from '@/components/mixins/restApi';
|
||||||
import { nodeHelpers } from '@/components/mixins/nodeHelpers';
|
import { nodeHelpers } from '@/components/mixins/nodeHelpers';
|
||||||
import { showMessage } from '@/components/mixins/showMessage';
|
import { showMessage } from '@/components/mixins/showMessage';
|
||||||
|
|
||||||
import { ICredentialsDecryptedResponse, IUpdateInformation } from '@/Interface';
|
import {
|
||||||
|
ICredentialsDecryptedResponse,
|
||||||
|
ICredentialsResponse,
|
||||||
|
IUpdateInformation,
|
||||||
|
} from '@/Interface';
|
||||||
import {
|
import {
|
||||||
CredentialInformation,
|
CredentialInformation,
|
||||||
ICredentialDataDecryptedObject,
|
ICredentialDataDecryptedObject,
|
||||||
|
@ -105,6 +109,7 @@ import {
|
||||||
ICredentialType,
|
ICredentialType,
|
||||||
ICredentialNodeAccess,
|
ICredentialNodeAccess,
|
||||||
INodeCredentialDescription,
|
INodeCredentialDescription,
|
||||||
|
INodeProperties,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
@ -172,15 +177,20 @@ export default mixins(
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
credentialProperties (): INodeProperties[] {
|
||||||
|
return this.credentialTypeData.properties.filter((propertyData: INodeProperties) => {
|
||||||
|
return !this.credentialTypeData.__overwrittenProperties || !this.credentialTypeData.__overwrittenProperties.includes(propertyData.name);
|
||||||
|
});
|
||||||
|
},
|
||||||
isOAuthType (): boolean {
|
isOAuthType (): boolean {
|
||||||
return this.credentialData && this.credentialData.type === 'oAuth2Api';
|
return this.credentialTypeData.name === 'oAuth2Api' || (this.credentialTypeData.extends !== undefined && this.credentialTypeData.extends.includes('oAuth2Api'));
|
||||||
},
|
},
|
||||||
isOAuthConnected (): boolean {
|
isOAuthConnected (): boolean {
|
||||||
if (this.isOAuthType === false) {
|
if (this.isOAuthType === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!this.credentialData.data.oauthTokenData;
|
return this.credentialData !== null && !!this.credentialData.data.oauthTokenData;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -192,7 +202,7 @@ export default mixins(
|
||||||
tempValue[name] = parameterData.value;
|
tempValue[name] = parameterData.value;
|
||||||
Vue.set(this, 'propertyValue', tempValue);
|
Vue.set(this, 'propertyValue', tempValue);
|
||||||
},
|
},
|
||||||
async createCredentials (): Promise<void> {
|
async createCredentials (doNotEmitData?: boolean): Promise<ICredentialsResponse | null> {
|
||||||
const nodesAccess = this.nodesAccess.map((nodeType) => {
|
const nodesAccess = this.nodesAccess.map((nodeType) => {
|
||||||
return {
|
return {
|
||||||
nodeType,
|
nodeType,
|
||||||
|
@ -211,18 +221,35 @@ export default mixins(
|
||||||
result = await this.restApi().createNewCredentials(newCredentials);
|
result = await this.restApi().createNewCredentials(newCredentials);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$showError(error, 'Problem Creating Credentials', 'There was a problem creating the credentials:');
|
this.$showError(error, 'Problem Creating Credentials', 'There was a problem creating the credentials:');
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add also to local store
|
// Add also to local store
|
||||||
this.$store.commit('addCredentials', result);
|
this.$store.commit('addCredentials', result);
|
||||||
|
|
||||||
this.$emit('credentialsCreated', result);
|
if (doNotEmitData !== true) {
|
||||||
|
this.$emit('credentialsCreated', result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
},
|
},
|
||||||
async oAuth2CredentialAuthorize () {
|
async oAuth2CredentialAuthorize () {
|
||||||
let url;
|
let url;
|
||||||
|
|
||||||
|
let credentialData = this.credentialData;
|
||||||
|
let newCredentials = false;
|
||||||
|
if (!credentialData) {
|
||||||
|
// Credentials did not get created yet. So create first before
|
||||||
|
// doing oauth authorize
|
||||||
|
credentialData = await this.createCredentials(true);
|
||||||
|
newCredentials = true;
|
||||||
|
if (credentialData === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
url = await this.restApi().oAuth2CredentialAuthorize(this.credentialData) as string;
|
url = await this.restApi().oAuth2CredentialAuthorize(credentialData) as string;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$showError(error, 'OAuth Authorization Error', 'Error generating authorization URL:');
|
this.$showError(error, 'OAuth Authorization Error', 'Error generating authorization URL:');
|
||||||
return;
|
return;
|
||||||
|
@ -241,13 +268,17 @@ export default mixins(
|
||||||
|
|
||||||
// Set some kind of data that status changes.
|
// Set some kind of data that status changes.
|
||||||
// As data does not get displayed directly it does not matter what data.
|
// As data does not get displayed directly it does not matter what data.
|
||||||
this.credentialData.data.oauthTokenData = {};
|
credentialData.data.oauthTokenData = {};
|
||||||
|
|
||||||
// Close the window
|
// Close the window
|
||||||
if (oauthPopup) {
|
if (oauthPopup) {
|
||||||
oauthPopup.close();
|
oauthPopup.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newCredentials === true) {
|
||||||
|
this.$emit('credentialsCreated', credentialData);
|
||||||
|
}
|
||||||
|
|
||||||
this.$showMessage({
|
this.$showMessage({
|
||||||
title: 'Connected',
|
title: 'Connected',
|
||||||
message: 'Got connected!',
|
message: 'Got connected!',
|
||||||
|
|
|
@ -35,6 +35,27 @@ export interface IGetCredentials {
|
||||||
get(type: string, name: string): Promise<ICredentialsEncrypted>;
|
get(type: string, name: string): Promise<ICredentialsEncrypted>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export abstract class ICredentials {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
data: string | undefined;
|
||||||
|
nodesAccess: ICredentialNodeAccess[];
|
||||||
|
|
||||||
|
constructor(name: string, type: string, nodesAccess: ICredentialNodeAccess[], data?: string) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.nodesAccess = nodesAccess;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract getData(encryptionKey: string, nodeType?: string): ICredentialDataDecryptedObject;
|
||||||
|
abstract getDataKey(key: string, encryptionKey: string, nodeType?: string): CredentialInformation;
|
||||||
|
abstract getDataToSave(): ICredentialsEncrypted;
|
||||||
|
abstract hasNodeAccess(nodeType: string): boolean;
|
||||||
|
abstract setData(data: ICredentialDataDecryptedObject, encryptionKey: string): void;
|
||||||
|
abstract setDataKey(key: string, data: CredentialInformation, encryptionKey: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
// Defines which nodes are allowed to access the credentials and
|
// Defines which nodes are allowed to access the credentials and
|
||||||
// when that access got grented from which user
|
// when that access got grented from which user
|
||||||
export interface ICredentialNodeAccess {
|
export interface ICredentialNodeAccess {
|
||||||
|
@ -57,11 +78,26 @@ export interface ICredentialsEncrypted {
|
||||||
data?: string;
|
data?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export abstract class ICredentialsHelper {
|
||||||
|
encryptionKey: string;
|
||||||
|
workflowCredentials: IWorkflowCredentials;
|
||||||
|
|
||||||
|
constructor(workflowCredentials: IWorkflowCredentials, encryptionKey: string) {
|
||||||
|
this.encryptionKey = encryptionKey;
|
||||||
|
this.workflowCredentials = workflowCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract getCredentials(name: string, type: string): ICredentials;
|
||||||
|
abstract getDecrypted(name: string, type: string): ICredentialDataDecryptedObject;
|
||||||
|
abstract updateCredentials(name: string, type: string, data: ICredentialDataDecryptedObject): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ICredentialType {
|
export interface ICredentialType {
|
||||||
name: string;
|
name: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
extends?: string[];
|
extends?: string[];
|
||||||
properties: INodeProperties[];
|
properties: INodeProperties[];
|
||||||
|
__overwrittenProperties?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICredentialTypes {
|
export interface ICredentialTypes {
|
||||||
|
@ -644,6 +680,7 @@ export interface IWorkflowExecuteHooks {
|
||||||
|
|
||||||
export interface IWorkflowExecuteAdditionalData {
|
export interface IWorkflowExecuteAdditionalData {
|
||||||
credentials: IWorkflowCredentials;
|
credentials: IWorkflowCredentials;
|
||||||
|
credentialsHelper: ICredentialsHelper;
|
||||||
encryptionKey: string;
|
encryptionKey: string;
|
||||||
executeWorkflow: (workflowInfo: IExecuteWorkflowInfo, additionalData: IWorkflowExecuteAdditionalData, inputData?: INodeExecutionData[]) => Promise<any>; // tslint:disable-line:no-any
|
executeWorkflow: (workflowInfo: IExecuteWorkflowInfo, additionalData: IWorkflowExecuteAdditionalData, inputData?: INodeExecutionData[]) => Promise<any>; // tslint:disable-line:no-any
|
||||||
// hooks?: IWorkflowExecuteHooks;
|
// hooks?: IWorkflowExecuteHooks;
|
||||||
|
@ -652,7 +689,6 @@ export interface IWorkflowExecuteAdditionalData {
|
||||||
httpRequest?: express.Request;
|
httpRequest?: express.Request;
|
||||||
restApiUrl: string;
|
restApiUrl: string;
|
||||||
timezone: string;
|
timezone: string;
|
||||||
updateCredentials: (name: string, type: string, data: ICredentialDataDecryptedObject, encryptionKey: string) => Promise<void>;
|
|
||||||
webhookBaseUrl: string;
|
webhookBaseUrl: string;
|
||||||
webhookTestBaseUrl: string;
|
webhookTestBaseUrl: string;
|
||||||
currentNodeParameters? : INodeParameters[];
|
currentNodeParameters? : INodeParameters[];
|
||||||
|
|
Loading…
Reference in a new issue