UNPKG

n8n

Version:

n8n Workflow Automation Tool

330 lines 14.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var CredentialsTester_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.CredentialsTester = void 0; const di_1 = require("@n8n/di"); const get_1 = __importDefault(require("lodash/get")); const n8n_core_1 = require("n8n-core"); const n8n_workflow_1 = require("n8n-workflow"); const credential_types_1 = require("../credential-types"); const node_types_1 = require("../node-types"); const WorkflowExecuteAdditionalData = __importStar(require("../workflow-execute-additional-data")); const constants_1 = require("../constants"); const credentials_helper_1 = require("../credentials-helper"); const { OAUTH2_CREDENTIAL_TEST_SUCCEEDED, OAUTH2_CREDENTIAL_TEST_FAILED } = constants_1.RESPONSE_ERROR_MESSAGES; const mockNodesData = { mock: { sourcePath: '', type: { description: { properties: [] }, }, }, }; const mockNodeTypes = { getKnownTypes() { return {}; }, getByName(nodeType) { return mockNodesData[nodeType]?.type; }, getByNameAndVersion(nodeType, version) { if (!mockNodesData[nodeType]) { throw new n8n_workflow_1.UnexpectedError(constants_1.RESPONSE_ERROR_MESSAGES.NO_NODE, { tags: { nodeType }, }); } return n8n_workflow_1.NodeHelpers.getVersionedNodeType(mockNodesData[nodeType].type, version); }, }; let CredentialsTester = CredentialsTester_1 = class CredentialsTester { constructor(logger, errorReporter, credentialTypes, nodeTypes, credentialsHelper) { this.logger = logger; this.errorReporter = errorReporter; this.credentialTypes = credentialTypes; this.nodeTypes = nodeTypes; this.credentialsHelper = credentialsHelper; } static hasAccessToken(credentialsDecrypted) { const oauthTokenData = credentialsDecrypted?.data?.oauthTokenData; if (!(0, n8n_core_1.isObjectLiteral)(oauthTokenData)) return false; return 'access_token' in oauthTokenData; } getCredentialTestFunction(credentialType) { const type = this.credentialTypes.getByName(credentialType); if (type.test) { return { testRequest: type.test, }; } const supportedNodes = this.credentialTypes.getSupportedNodes(credentialType); for (const nodeName of supportedNodes) { const node = this.nodeTypes.getByName(nodeName); const allNodeTypes = []; if (node instanceof n8n_workflow_1.VersionedNodeType) { allNodeTypes.push(...Object.values(node.nodeVersions)); } else { allNodeTypes.push(node); } for (const nodeType of allNodeTypes) { for (const { name, testedBy } of nodeType.description.credentials ?? []) { if (name === credentialType && (this.credentialTypes.getParentTypes(name).includes('oAuth2Api') || name === 'oAuth2Api')) { return async function oauth2CredTest(cred) { return CredentialsTester_1.hasAccessToken(cred) ? { status: 'OK', message: OAUTH2_CREDENTIAL_TEST_SUCCEEDED, } : { status: 'Error', message: OAUTH2_CREDENTIAL_TEST_FAILED, }; }; } if (name === credentialType && !!testedBy) { if (typeof testedBy === 'string') { if (node instanceof n8n_workflow_1.VersionedNodeType) { const versions = Object.keys(node.nodeVersions).sort().reverse(); for (const version of versions) { const versionedNode = node.nodeVersions[parseInt(version, 10)]; const credentialTest = versionedNode.methods?.credentialTest; if (credentialTest && testedBy in credentialTest) { return credentialTest[testedBy]; } } } return node.methods?.credentialTest[testedBy]; } return { nodeType, testRequest: testedBy, }; } } } } return undefined; } async testCredentials(userId, credentialType, credentialsDecrypted) { const credentialTestFunction = this.getCredentialTestFunction(credentialType); if (credentialTestFunction === undefined) { return { status: 'Error', message: 'No testing function found for this credential.', }; } if (credentialsDecrypted.data) { try { const additionalData = await WorkflowExecuteAdditionalData.getBase(userId); credentialsDecrypted.data = this.credentialsHelper.applyDefaultsAndOverwrites(additionalData, credentialsDecrypted.data, credentialType, 'internal', undefined, undefined, await this.credentialsHelper.credentialCanUseExternalSecrets(credentialsDecrypted)); } catch (error) { this.logger.debug('Credential test failed', error); return { status: 'Error', message: error.message.toString(), }; } } if (typeof credentialTestFunction === 'function') { const context = new n8n_core_1.CredentialTestContext(); return credentialTestFunction.call(context, credentialsDecrypted); } let nodeType; if (credentialTestFunction.nodeType) { nodeType = credentialTestFunction.nodeType; } else { nodeType = this.nodeTypes.getByNameAndVersion('n8n-nodes-base.noOp'); } const node = { id: 'temp', parameters: {}, name: 'Temp-Node', type: nodeType.description.name, typeVersion: Array.isArray(nodeType.description.version) ? nodeType.description.version.slice(-1)[0] : nodeType.description.version, position: [0, 0], credentials: { [credentialType]: { id: credentialsDecrypted.id, name: credentialsDecrypted.name, }, }, }; const workflowData = { nodes: [node], connections: {}, }; const nodeTypeCopy = { description: { ...nodeType.description, credentials: [ { name: credentialType, required: true, }, ], properties: [ { displayName: 'Temp', name: 'temp', type: 'string', routing: { request: credentialTestFunction.testRequest.request, }, default: '', }, ], }, }; mockNodesData[nodeTypeCopy.description.name] = { sourcePath: '', type: nodeTypeCopy, }; const workflow = new n8n_workflow_1.Workflow({ nodes: workflowData.nodes, connections: workflowData.connections, active: false, nodeTypes: mockNodeTypes, }); const mode = 'internal'; const runIndex = 0; const inputData = { main: [[{ json: {} }]], }; const connectionInputData = []; const runExecutionData = { resultData: { runData: {}, }, }; const additionalData = await WorkflowExecuteAdditionalData.getBase(userId, node.parameters); const executeData = { node, data: {}, source: null }; const executeFunctions = new n8n_core_1.ExecuteContext(workflow, node, additionalData, mode, runExecutionData, runIndex, connectionInputData, inputData, executeData, []); const routingNode = new n8n_core_1.RoutingNode(executeFunctions, nodeTypeCopy, credentialsDecrypted); let response; try { response = await routingNode.runNode(); } catch (error) { this.errorReporter.error(error); if (error.cause?.response) { const errorResponseData = { statusCode: error.cause.response.status, statusMessage: error.cause.response.statusText, }; if (credentialTestFunction.testRequest.rules) { for (const rule of credentialTestFunction.testRequest.rules) { if (rule.type === 'responseCode') { if (errorResponseData.statusCode === rule.properties.value) { return { status: 'Error', message: rule.properties.message, }; } } } } if (errorResponseData.statusCode < 199 || errorResponseData.statusCode > 299) { return { status: 'Error', message: errorResponseData.statusMessage || `Received HTTP status code: ${errorResponseData.statusCode}`, }; } } else if (error.cause?.code) { return { status: 'Error', message: error.cause.code, }; } this.logger.debug('Credential test failed', error); return { status: 'Error', message: error.message.toString(), }; } finally { delete mockNodesData[nodeTypeCopy.description.name]; } if (credentialTestFunction.testRequest.rules && Array.isArray(credentialTestFunction.testRequest.rules)) { for (const rule of credentialTestFunction.testRequest.rules) { if (rule.type === 'responseSuccessBody') { const responseData = response[0][0].json; if ((0, get_1.default)(responseData, rule.properties.key) === rule.properties.value) { return { status: 'Error', message: rule.properties.message, }; } } } } return { status: 'OK', message: 'Connection successful!', }; } }; exports.CredentialsTester = CredentialsTester; exports.CredentialsTester = CredentialsTester = CredentialsTester_1 = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [n8n_core_1.Logger, n8n_core_1.ErrorReporter, credential_types_1.CredentialTypes, node_types_1.NodeTypes, credentials_helper_1.CredentialsHelper]) ], CredentialsTester); //# sourceMappingURL=credentials-tester.service.js.map