UNPKG

n8n

Version:

n8n Workflow Automation Tool

432 lines 20.9 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 }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FrontendService = void 0; const config_1 = require("@n8n/config"); const di_1 = require("@n8n/di"); const fs_1 = require("fs"); const promises_1 = require("fs/promises"); const uniq_1 = __importDefault(require("lodash/uniq")); const n8n_core_1 = require("n8n-core"); const path_1 = __importDefault(require("path")); const config_2 = __importDefault(require("../config")); const constants_1 = require("../constants"); const credential_types_1 = require("../credential-types"); const credentials_overwrites_1 = require("../credentials-overwrites"); const helpers_ee_1 = require("../ldap.ee/helpers.ee"); const license_1 = require("../license"); const load_nodes_and_credentials_1 = require("../load-nodes-and-credentials"); const modules_config_1 = require("../modules/modules.config"); const public_api_1 = require("../public-api"); const push_config_1 = require("../push/push.config"); const saml_helpers_1 = require("../sso.ee/saml/saml-helpers"); const sso_helpers_1 = require("../sso.ee/sso-helpers"); const email_1 = require("../user-management/email"); const workflow_history_helper_ee_1 = require("../workflows/workflow-history.ee/workflow-history-helper.ee"); const url_service_1 = require("./url.service"); let FrontendService = class FrontendService { constructor(globalConfig, logger, loadNodesAndCredentials, credentialTypes, credentialsOverwrites, license, mailer, instanceSettings, urlService, securityConfig, modulesConfig, pushConfig) { this.globalConfig = globalConfig; this.logger = logger; this.loadNodesAndCredentials = loadNodesAndCredentials; this.credentialTypes = credentialTypes; this.credentialsOverwrites = credentialsOverwrites; this.license = license; this.mailer = mailer; this.instanceSettings = instanceSettings; this.urlService = urlService; this.securityConfig = securityConfig; this.modulesConfig = modulesConfig; this.pushConfig = pushConfig; loadNodesAndCredentials.addPostProcessor(async () => await this.generateTypes()); void this.generateTypes(); this.initSettings(); if (this.globalConfig.nodes.communityPackages.enabled) { void Promise.resolve().then(() => __importStar(require('../services/community-packages.service'))).then(({ CommunityPackagesService }) => { this.communityPackagesService = di_1.Container.get(CommunityPackagesService); }); } } initSettings() { const instanceBaseUrl = this.urlService.getInstanceBaseUrl(); const restEndpoint = this.globalConfig.endpoints.rest; const telemetrySettings = { enabled: this.globalConfig.diagnostics.enabled, }; if (telemetrySettings.enabled) { const conf = this.globalConfig.diagnostics.frontendConfig; const [key, url] = conf.split(';'); if (!key || !url) { this.logger.warn('Diagnostics frontend config is invalid'); telemetrySettings.enabled = false; } telemetrySettings.config = { key, url }; } this.settings = { inE2ETests: constants_1.inE2ETests, isDocker: this.instanceSettings.isDocker, databaseType: this.globalConfig.database.type, previewMode: process.env.N8N_PREVIEW_MODE === 'true', endpointForm: this.globalConfig.endpoints.form, endpointFormTest: this.globalConfig.endpoints.formTest, endpointFormWaiting: this.globalConfig.endpoints.formWaiting, endpointMcp: this.globalConfig.endpoints.mcp, endpointMcpTest: this.globalConfig.endpoints.mcpTest, endpointWebhook: this.globalConfig.endpoints.webhook, endpointWebhookTest: this.globalConfig.endpoints.webhookTest, endpointWebhookWaiting: this.globalConfig.endpoints.webhookWaiting, saveDataErrorExecution: config_2.default.getEnv('executions.saveDataOnError'), saveDataSuccessExecution: config_2.default.getEnv('executions.saveDataOnSuccess'), saveManualExecutions: config_2.default.getEnv('executions.saveDataManualExecutions'), saveExecutionProgress: config_2.default.getEnv('executions.saveExecutionProgress'), executionTimeout: config_2.default.getEnv('executions.timeout'), maxExecutionTimeout: config_2.default.getEnv('executions.maxTimeout'), workflowCallerPolicyDefaultOption: this.globalConfig.workflows.callerPolicyDefaultOption, timezone: this.globalConfig.generic.timezone, urlBaseWebhook: this.urlService.getWebhookBaseUrl(), urlBaseEditor: instanceBaseUrl, binaryDataMode: config_2.default.getEnv('binaryDataManager.mode'), nodeJsVersion: process.version.replace(/^v/, ''), versionCli: constants_1.N8N_VERSION, concurrency: config_2.default.getEnv('executions.concurrency.productionLimit'), authCookie: { secure: this.globalConfig.auth.cookie.secure, }, releaseChannel: this.globalConfig.generic.releaseChannel, oauthCallbackUrls: { oauth1: `${instanceBaseUrl}/${restEndpoint}/oauth1-credential/callback`, oauth2: `${instanceBaseUrl}/${restEndpoint}/oauth2-credential/callback`, }, versionNotifications: { enabled: this.globalConfig.versionNotifications.enabled, endpoint: this.globalConfig.versionNotifications.endpoint, infoUrl: this.globalConfig.versionNotifications.infoUrl, }, instanceId: this.instanceSettings.instanceId, telemetry: telemetrySettings, posthog: { enabled: this.globalConfig.diagnostics.enabled, apiHost: this.globalConfig.diagnostics.posthogConfig.apiHost, apiKey: this.globalConfig.diagnostics.posthogConfig.apiKey, autocapture: false, disableSessionRecording: config_2.default.getEnv('deployment.type') !== 'cloud', debug: this.globalConfig.logging.level === 'debug', }, personalizationSurveyEnabled: config_2.default.getEnv('personalization.enabled') && this.globalConfig.diagnostics.enabled, defaultLocale: config_2.default.getEnv('defaultLocale'), userManagement: { quota: this.license.getUsersLimit(), showSetupOnFirstLoad: !config_2.default.getEnv('userManagement.isInstanceOwnerSetUp'), smtpSetup: this.mailer.isEmailSetUp, authenticationMethod: (0, sso_helpers_1.getCurrentAuthenticationMethod)(), }, sso: { saml: { loginEnabled: false, loginLabel: '', }, ldap: { loginEnabled: false, loginLabel: '', }, }, publicApi: { enabled: (0, public_api_1.isApiEnabled)(), latestVersion: 1, path: this.globalConfig.publicApi.path, swaggerUi: { enabled: !this.globalConfig.publicApi.swaggerUiDisabled, }, }, workflowTagsDisabled: this.globalConfig.tags.disabled, logLevel: this.globalConfig.logging.level, hiringBannerEnabled: config_2.default.getEnv('hiringBanner.enabled'), aiAssistant: { enabled: false, }, templates: { enabled: this.globalConfig.templates.enabled, host: this.globalConfig.templates.host, }, executionMode: config_2.default.getEnv('executions.mode'), pushBackend: this.pushConfig.backend, communityNodesEnabled: this.globalConfig.nodes.communityPackages.enabled, deployment: { type: config_2.default.getEnv('deployment.type'), }, allowedModules: { builtIn: process.env.NODE_FUNCTION_ALLOW_BUILTIN?.split(',') ?? undefined, external: process.env.NODE_FUNCTION_ALLOW_EXTERNAL?.split(',') ?? undefined, }, enterprise: { sharing: false, ldap: false, saml: false, logStreaming: false, advancedExecutionFilters: false, variables: false, sourceControl: false, auditLogs: false, externalSecrets: false, showNonProdBanner: false, debugInEditor: false, binaryDataS3: false, workflowHistory: false, workerView: false, advancedPermissions: false, projects: { team: { limit: 0, }, }, }, mfa: { enabled: false, }, hideUsagePage: config_2.default.getEnv('hideUsagePage'), license: { consumerId: 'unknown', environment: this.globalConfig.license.tenantId === 1 ? 'production' : 'staging', }, variables: { limit: 0, }, expressions: { evaluator: config_2.default.getEnv('expression.evaluator'), }, banners: { dismissed: [], }, askAi: { enabled: false, }, aiCredits: { enabled: false, credits: 0, }, workflowHistory: { pruneTime: -1, licensePruneTime: -1, }, pruning: { isEnabled: this.globalConfig.executions.pruneData, maxAge: this.globalConfig.executions.pruneDataMaxAge, maxCount: this.globalConfig.executions.pruneDataMaxCount, }, security: { blockFileAccessToN8nFiles: this.securityConfig.blockFileAccessToN8nFiles, }, easyAIWorkflowOnboarded: false, partialExecution: this.globalConfig.partialExecutions, folders: { enabled: false, }, insights: { enabled: this.modulesConfig.modules.includes('insights'), summary: true, dashboard: false, }, }; } async generateTypes() { this.overwriteCredentialsProperties(); const { staticCacheDir } = this.instanceSettings; await (0, promises_1.mkdir)(path_1.default.join(staticCacheDir, 'types'), { recursive: true }); const { credentials, nodes } = this.loadNodesAndCredentials.types; this.writeStaticJSON('nodes', nodes); this.writeStaticJSON('credentials', credentials); } getSettings() { const restEndpoint = this.globalConfig.endpoints.rest; const instanceBaseUrl = this.urlService.getInstanceBaseUrl(); this.settings.urlBaseWebhook = this.urlService.getWebhookBaseUrl(); this.settings.urlBaseEditor = instanceBaseUrl; this.settings.oauthCallbackUrls = { oauth1: `${instanceBaseUrl}/${restEndpoint}/oauth1-credential/callback`, oauth2: `${instanceBaseUrl}/${restEndpoint}/oauth2-credential/callback`, }; Object.assign(this.settings.userManagement, { quota: this.license.getUsersLimit(), authenticationMethod: (0, sso_helpers_1.getCurrentAuthenticationMethod)(), showSetupOnFirstLoad: !config_2.default.getEnv('userManagement.isInstanceOwnerSetUp'), }); let dismissedBanners = []; try { dismissedBanners = config_2.default.getEnv('ui.banners.dismissed') ?? []; } catch { } this.settings.banners.dismissed = dismissedBanners; try { this.settings.easyAIWorkflowOnboarded = config_2.default.getEnv('easyAIWorkflowOnboarded') ?? false; } catch { this.settings.easyAIWorkflowOnboarded = false; } const isS3Selected = config_2.default.getEnv('binaryDataManager.mode') === 's3'; const isS3Available = config_2.default.getEnv('binaryDataManager.availableModes').includes('s3'); const isS3Licensed = this.license.isBinaryDataS3Licensed(); const isAiAssistantEnabled = this.license.isAiAssistantEnabled(); const isAskAiEnabled = this.license.isAskAiEnabled(); const isAiCreditsEnabled = this.license.isAiCreditsEnabled(); this.settings.license.planName = this.license.getPlanName(); this.settings.license.consumerId = this.license.getConsumerId(); Object.assign(this.settings.enterprise, { sharing: this.license.isSharingEnabled(), logStreaming: this.license.isLogStreamingEnabled(), ldap: this.license.isLdapEnabled(), saml: this.license.isSamlEnabled(), advancedExecutionFilters: this.license.isAdvancedExecutionFiltersEnabled(), variables: this.license.isVariablesEnabled(), sourceControl: this.license.isSourceControlLicensed(), externalSecrets: this.license.isExternalSecretsEnabled(), showNonProdBanner: this.license.isFeatureEnabled(constants_1.LICENSE_FEATURES.SHOW_NON_PROD_BANNER), debugInEditor: this.license.isDebugInEditorLicensed(), binaryDataS3: isS3Available && isS3Selected && isS3Licensed, workflowHistory: this.license.isWorkflowHistoryLicensed() && config_2.default.getEnv('workflowHistory.enabled'), workerView: this.license.isWorkerViewLicensed(), advancedPermissions: this.license.isAdvancedPermissionsLicensed(), }); if (this.license.isLdapEnabled()) { Object.assign(this.settings.sso.ldap, { loginLabel: (0, helpers_ee_1.getLdapLoginLabel)(), loginEnabled: config_2.default.getEnv('sso.ldap.loginEnabled'), }); } if (this.license.isSamlEnabled()) { Object.assign(this.settings.sso.saml, { loginLabel: (0, saml_helpers_1.getSamlLoginLabel)(), loginEnabled: config_2.default.getEnv('sso.saml.loginEnabled'), }); } if (this.license.isVariablesEnabled()) { this.settings.variables.limit = this.license.getVariablesLimit(); } if (this.license.isWorkflowHistoryLicensed() && config_2.default.getEnv('workflowHistory.enabled')) { Object.assign(this.settings.workflowHistory, { pruneTime: (0, workflow_history_helper_ee_1.getWorkflowHistoryPruneTime)(), licensePruneTime: (0, workflow_history_helper_ee_1.getWorkflowHistoryLicensePruneTime)(), }); } if (this.communityPackagesService) { this.settings.missingPackages = this.communityPackagesService.hasMissingPackages; } if (isAiAssistantEnabled) { this.settings.aiAssistant.enabled = isAiAssistantEnabled; } if (isAskAiEnabled) { this.settings.askAi.enabled = isAskAiEnabled; } if (isAiCreditsEnabled) { this.settings.aiCredits.enabled = isAiCreditsEnabled; this.settings.aiCredits.credits = this.license.getAiCredits(); } Object.assign(this.settings.insights, { enabled: this.modulesConfig.loadedModules.has('insights'), summary: this.license.isInsightsSummaryEnabled(), dashboard: this.license.isInsightsDashboardEnabled(), }); this.settings.mfa.enabled = config_2.default.get('mfa.enabled'); this.settings.executionMode = config_2.default.getEnv('executions.mode'); this.settings.binaryDataMode = config_2.default.getEnv('binaryDataManager.mode'); this.settings.enterprise.projects.team.limit = this.license.getTeamProjectLimit(); this.settings.folders.enabled = this.license.isFoldersEnabled(); return this.settings; } writeStaticJSON(name, data) { const { staticCacheDir } = this.instanceSettings; const filePath = path_1.default.join(staticCacheDir, `types/${name}.json`); const stream = (0, fs_1.createWriteStream)(filePath, 'utf-8'); stream.write('[\n'); data.forEach((entry, index) => { stream.write(JSON.stringify(entry)); if (index !== data.length - 1) stream.write(','); stream.write('\n'); }); stream.write(']\n'); stream.end(); } overwriteCredentialsProperties() { const { credentials } = this.loadNodesAndCredentials.types; const credentialsOverwrites = this.credentialsOverwrites.getAll(); for (const credential of credentials) { const overwrittenProperties = []; this.credentialTypes .getParentTypes(credential.name) .reverse() .map((name) => credentialsOverwrites[name]) .forEach((overwrite) => { if (overwrite) overwrittenProperties.push(...Object.keys(overwrite)); }); if (credential.name in credentialsOverwrites) { overwrittenProperties.push(...Object.keys(credentialsOverwrites[credential.name])); } if (overwrittenProperties.length) { credential.__overwrittenProperties = (0, uniq_1.default)(overwrittenProperties); } } } }; exports.FrontendService = FrontendService; exports.FrontendService = FrontendService = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [config_1.GlobalConfig, n8n_core_1.Logger, load_nodes_and_credentials_1.LoadNodesAndCredentials, credential_types_1.CredentialTypes, credentials_overwrites_1.CredentialsOverwrites, license_1.License, email_1.UserManagementMailer, n8n_core_1.InstanceSettings, url_service_1.UrlService, config_1.SecurityConfig, modules_config_1.ModulesConfig, push_config_1.PushConfig]) ], FrontendService); //# sourceMappingURL=frontend.service.js.map