diff --git a/.github/workflows/ci-master.yml b/.github/workflows/ci-master.yml index cbfe0df95a92b..e3ef37b180986 100644 --- a/.github/workflows/ci-master.yml +++ b/.github/workflows/ci-master.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - node-version: [16.x] + node-version: [14.x, 16.x] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/ci-pull-requests.yml b/.github/workflows/ci-pull-requests.yml index f659b259e0d89..130e1753bdb6e 100644 --- a/.github/workflows/ci-pull-requests.yml +++ b/.github/workflows/ci-pull-requests.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: - node-version: [16.x] + node-version: [14.x, 16.x] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index bb6b52cd0d570..232d0f508bf40 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -31,7 +31,7 @@ jobs: strategy: matrix: - node-version: [16.x] + node-version: [14.x, 16.x] steps: - name: Call Start URL - optionally diff --git a/cypress/e2e/1-workflows.cy.ts b/cypress/e2e/1-workflows.cy.ts index 5d0a3cc8066b6..303ec68b5a2bf 100644 --- a/cypress/e2e/1-workflows.cy.ts +++ b/cypress/e2e/1-workflows.cy.ts @@ -11,6 +11,8 @@ const lastName = randLastName(); const WorkflowsPage = new WorkflowsPageClass(); const WorkflowPage = new WorkflowPageClass(); +const multipleWorkflowsCount = 5; + describe('Workflows', () => { before(() => { cy.resetAll(); @@ -38,31 +40,39 @@ describe('Workflows', () => { WorkflowPage.getters.workflowTags().should('contain.text', 'some-tag-2'); }); - it('should create a new workflow using add workflow button', () => { + it('should create multiple new workflows using add workflow button', () => { WorkflowsPage.getters.newWorkflowButtonCard().should('not.exist'); - WorkflowsPage.getters.createWorkflowButton().click(); - cy.createFixtureWorkflow('Test_workflow_2.json', `Add Workflow Button Workflow ${uuid()}`); + [...Array(multipleWorkflowsCount).keys()].forEach(() => { + cy.visit(WorkflowsPage.url); + WorkflowsPage.getters.createWorkflowButton().click(); + + cy.createFixtureWorkflow('Test_workflow_2.json', `My New Workflow ${uuid()}`); - WorkflowPage.getters.workflowTags().should('contain.text', 'other-tag-1'); - WorkflowPage.getters.workflowTags().should('contain.text', 'other-tag-2'); + WorkflowPage.getters.workflowTags().should('contain.text', 'other-tag-1'); + WorkflowPage.getters.workflowTags().should('contain.text', 'other-tag-2'); + }); }); it('should search for a workflow', () => { + // One Result WorkflowsPage.getters.searchBar().type('Empty State Card Workflow'); - WorkflowsPage.getters.workflowCards().should('have.length', 1); WorkflowsPage.getters .workflowCard('Empty State Card Workflow') .should('contain.text', 'Empty State Card Workflow'); - WorkflowsPage.getters.searchBar().clear().type('Add Workflow Button Workflow'); + // Multiple Results + WorkflowsPage.getters.searchBar().clear().type('My New Workflow'); + WorkflowsPage.getters.workflowCards().should('have.length', multipleWorkflowsCount); + WorkflowsPage.getters.workflowCard('My New Workflow').should('contain.text', 'My New Workflow'); - WorkflowsPage.getters.workflowCards().should('have.length', 1); - WorkflowsPage.getters - .workflowCard('Add Workflow Button Workflow') - .should('contain.text', 'Add Workflow Button Workflow'); + // All Results + WorkflowsPage.getters.searchBar().clear().type('Workflow'); + WorkflowsPage.getters.workflowCards().should('have.length', multipleWorkflowsCount + 1); + WorkflowsPage.getters.workflowCard('Workflow').should('contain.text', 'Workflow'); + // No Results WorkflowsPage.getters.searchBar().clear().type('Some non-existent workflow'); WorkflowsPage.getters.workflowCards().should('not.exist'); @@ -70,7 +80,7 @@ describe('Workflows', () => { }); it('should delete all the workflows', () => { - WorkflowsPage.getters.workflowCards().should('have.length', 2); + WorkflowsPage.getters.workflowCards().should('have.length', multipleWorkflowsCount + 1); WorkflowsPage.getters.workflowCards().each(($el) => { const workflowName = $el.find('[data-test-id="workflow-card-name"]').text(); diff --git a/cypress/e2e/10-undo-redo.cy.ts b/cypress/e2e/10-undo-redo.cy.ts index 515cc611902b9..e76091b553382 100644 --- a/cypress/e2e/10-undo-redo.cy.ts +++ b/cypress/e2e/10-undo-redo.cy.ts @@ -39,11 +39,9 @@ describe('Undo/Redo', () => { WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME); WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME); WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME); - WorkflowPage.getters.nodeConnections().first().trigger('mouseover', { force: true }); - cy.get('.connection-actions .add').invoke('show'); - cy.get('.connection-actions .add').should('be.visible'); - cy.get('.connection-actions .add').click(); - WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME); + WorkflowPage.getters.nodeConnections().realHover(); + cy.get('.connection-actions .add').filter(':visible').click(); + WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME, false); WorkflowPage.actions.zoomToFit(); WorkflowPage.actions.hitUndo(); WorkflowPage.getters.canvasNodes().should('have.have.length', 3); @@ -141,8 +139,8 @@ describe('Undo/Redo', () => { it('should undo/redo deleting a connection by pressing delete button', () => { WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME); WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME); - WorkflowPage.getters.nodeConnections().first().trigger('mouseover', { force: true }); - cy.get('.connection-actions .delete').click(); + WorkflowPage.getters.nodeConnections().realHover(); + cy.get('.connection-actions .delete').filter(':visible').should('be.visible').click(); WorkflowPage.getters.nodeConnections().should('have.length', 0); WorkflowPage.actions.hitUndo(); WorkflowPage.getters.nodeConnections().should('have.length', 1); diff --git a/cypress/e2e/12-canvas.cy.ts b/cypress/e2e/12-canvas.cy.ts index 062412e8887a0..3651ce163a661 100644 --- a/cypress/e2e/12-canvas.cy.ts +++ b/cypress/e2e/12-canvas.cy.ts @@ -61,11 +61,9 @@ describe('Canvas Actions', () => { it('should add note between two connected nodes', () => { WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME); WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME); - WorkflowPage.getters.nodeConnections().first().trigger('mouseover', { force: true }); - cy.get('.connection-actions .add').as('AddNodeConnectionButton'); - cy.get('@AddNodeConnectionButton').invoke('show'); - cy.get('@AddNodeConnectionButton').should('be.visible').click(); - WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME); + WorkflowPage.getters.nodeConnections().first().realHover(); + cy.get('.connection-actions .add').filter(':visible').should('be.visible').click() + WorkflowPage.actions.addNodeToCanvas(SET_NODE_NAME, false); WorkflowPage.getters.canvasNodes().should('have.length', 3); WorkflowPage.getters.nodeConnections().should('have.length', 2); // And last node should be pushed to the right @@ -219,8 +217,8 @@ describe('Canvas Actions', () => { it('should delete connections by pressing the delete button', () => { WorkflowPage.actions.addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME); WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME); - WorkflowPage.getters.nodeConnections().first().trigger('mouseover', { force: true }); - cy.get('.connection-actions .delete').click(); + WorkflowPage.getters.nodeConnections().first().realHover(); + cy.get('.connection-actions .delete').filter(':visible').should('be.visible').click(); WorkflowPage.getters.nodeConnections().should('have.length', 0); }); diff --git a/cypress/e2e/2-credentials.cy.ts b/cypress/e2e/2-credentials.cy.ts index 4430acf0704c4..f94a11571d777 100644 --- a/cypress/e2e/2-credentials.cy.ts +++ b/cypress/e2e/2-credentials.cy.ts @@ -151,7 +151,7 @@ describe('Credentials', () => { it('should correctly render required and optional credentials', () => { workflowPage.actions.visit(); cy.waitForLoad(); - workflowPage.actions.addNodeToCanvas(PIPEDRIVE_NODE_NAME, true); + workflowPage.actions.addNodeToCanvas(PIPEDRIVE_NODE_NAME, true, true); cy.get('body').type('{downArrow}'); cy.get('body').type('{enter}'); // Select incoming authentication diff --git a/cypress/e2e/5-ndv.cy.ts b/cypress/e2e/5-ndv.cy.ts index d4829945507aa..9fead48e51a4c 100644 --- a/cypress/e2e/5-ndv.cy.ts +++ b/cypress/e2e/5-ndv.cy.ts @@ -53,7 +53,7 @@ describe('NDV', () => { }); it('should show correct validation state for resource locator params', () => { - workflowPage.actions.addNodeToCanvas('Typeform', true); + workflowPage.actions.addNodeToCanvas('Typeform', true, false); ndv.getters.container().should('be.visible'); cy.get('.has-issues').should('have.length', 0); cy.get('[class*=hasIssues]').should('have.length', 0); @@ -66,7 +66,7 @@ describe('NDV', () => { it('should show validation errors only after blur or re-opening of NDV', () => { workflowPage.actions.addNodeToCanvas('Manual Trigger'); - workflowPage.actions.addNodeToCanvas('Airtable', true); + workflowPage.actions.addNodeToCanvas('Airtable', true, true); ndv.getters.container().should('be.visible'); cy.get('.has-issues').should('have.length', 0); ndv.getters.parameterInput('table').find('input').eq(1).focus().blur(); diff --git a/cypress/pages/workflow.ts b/cypress/pages/workflow.ts index 98f408e0ed932..67a16c4421417 100644 --- a/cypress/pages/workflow.ts +++ b/cypress/pages/workflow.ts @@ -92,8 +92,11 @@ export class WorkflowPage extends BasePage { this.getters.nodeCreatorSearchBar().type('{enter}'); cy.get('body').type('{esc}'); }, - addNodeToCanvas: (nodeDisplayName: string, preventNdvClose?: boolean) => { - this.getters.nodeCreatorPlusButton().click(); + addNodeToCanvas: (nodeDisplayName: string, plusButtonClick = true, preventNdvClose?: boolean) => { + if (plusButtonClick) { + this.getters.nodeCreatorPlusButton().click(); + } + this.getters.nodeCreatorSearchBar().type(nodeDisplayName); this.getters.nodeCreatorSearchBar().type('{enter}'); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index beb5f17c9d227..9a686ab2d0383 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -23,7 +23,7 @@ // // -- This will overwrite an existing command -- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) - +import "cypress-real-events"; import { WorkflowsPage, SigninPage, SignupPage } from '../pages'; import { N8N_AUTH_COOKIE } from '../constants'; import { WorkflowPage as WorkflowPageClass } from '../pages/workflow'; diff --git a/docker/images/n8n-custom/Dockerfile b/docker/images/n8n-custom/Dockerfile index 6f49901cdced8..76ee6ded63d80 100644 --- a/docker/images/n8n-custom/Dockerfile +++ b/docker/images/n8n-custom/Dockerfile @@ -6,6 +6,7 @@ FROM n8nio/base:${NODE_VERSION} as builder COPY turbo.json package.json .npmrc pnpm-lock.yaml pnpm-workspace.yaml tsconfig.json ./ COPY scripts ./scripts COPY packages ./packages +COPY patches ./patches RUN apk add --update libc6-compat jq RUN corepack enable && corepack prepare --activate @@ -15,6 +16,7 @@ USER node RUN pnpm install --frozen-lockfile RUN pnpm build RUN rm -rf node_modules +RUN jq 'del(.pnpm.patchedDependencies)' package.json > package.json.tmp; mv package.json.tmp package.json RUN jq '{name: .name, version: .version}' packages/editor-ui/package.json > editor-ui.tmp; mv editor-ui.tmp packages/editor-ui/package.json RUN jq '{name: .name, version: .version}' packages/design-system/package.json > design-system.tmp; mv design-system.tmp packages/design-system/package.json RUN NODE_ENV=production pnpm install --prod --no-optional diff --git a/package.json b/package.json index ff0f3e858d5b7..7011e19246db6 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@types/node": "^16.11.22", "cross-env": "^7.0.3", "cypress": "^10.0.3", + "cypress-real-events": "^1.7.6", "jest": "^29.3.1", "jest-environment-jsdom": "^29.3.1", "jest-mock": "^29.3.1", diff --git a/packages/cli/src/CredentialsOverwrites.ts b/packages/cli/src/CredentialsOverwrites.ts index 414f3eb349e5d..c3a5702df113f 100644 --- a/packages/cli/src/CredentialsOverwrites.ts +++ b/packages/cli/src/CredentialsOverwrites.ts @@ -1,18 +1,15 @@ +import config from '@/config'; import type { ICredentialDataDecryptedObject, ICredentialTypes } from 'n8n-workflow'; import { deepCopy, LoggerProxy as Logger, jsonParse } from 'n8n-workflow'; import type { ICredentialsOverwrite } from '@/Interfaces'; -import * as GenericHelpers from '@/GenericHelpers'; class CredentialsOverwritesClass { private overwriteData: ICredentialsOverwrite = {}; private resolvedTypes: string[] = []; - constructor(private credentialTypes: ICredentialTypes) {} - - async init() { - const data = (await GenericHelpers.getConfigValue('credentials.overwrite.data')) as string; - + constructor(private credentialTypes: ICredentialTypes) { + const data = config.getEnv('credentials.overwrite.data'); const overwriteData = jsonParse(data, { errorMessage: 'The credentials-overwrite is not valid JSON.', }); diff --git a/packages/cli/src/Db.ts b/packages/cli/src/Db.ts index 76bdd1e905781..68ff6a0adaf38 100644 --- a/packages/cli/src/Db.ts +++ b/packages/cli/src/Db.ts @@ -14,7 +14,6 @@ import type { import { DataSource as Connection } from 'typeorm'; import type { TlsOptions } from 'tls'; import type { DatabaseType, IDatabaseCollections } from '@/Interfaces'; -import * as GenericHelpers from '@/GenericHelpers'; import config from '@/config'; @@ -44,17 +43,13 @@ export function linkRepository( return connection.getRepository(entityClass); } -export async function getConnectionOptions(dbType: DatabaseType): Promise { +export function getConnectionOptions(dbType: DatabaseType): ConnectionOptions { switch (dbType) { case 'postgresdb': - const sslCa = (await GenericHelpers.getConfigValue('database.postgresdb.ssl.ca')) as string; - const sslCert = (await GenericHelpers.getConfigValue( - 'database.postgresdb.ssl.cert', - )) as string; - const sslKey = (await GenericHelpers.getConfigValue('database.postgresdb.ssl.key')) as string; - const sslRejectUnauthorized = (await GenericHelpers.getConfigValue( - 'database.postgresdb.ssl.rejectUnauthorized', - )) as boolean; + const sslCa = config.getEnv('database.postgresdb.ssl.ca'); + const sslCert = config.getEnv('database.postgresdb.ssl.cert'); + const sslKey = config.getEnv('database.postgresdb.ssl.key'); + const sslRejectUnauthorized = config.getEnv('database.postgresdb.ssl.rejectUnauthorized'); let ssl: TlsOptions | undefined; if (sslCa !== '' || sslCert !== '' || sslKey !== '' || !sslRejectUnauthorized) { @@ -68,7 +63,7 @@ export async function getConnectionOptions(dbType: DatabaseType): Promise { if (isInitialized) return collections; - const dbType = (await GenericHelpers.getConfigValue('database.type')) as DatabaseType; - const connectionOptions = testConnectionOptions ?? (await getConnectionOptions(dbType)); + const dbType = config.getEnv('database.type'); + const connectionOptions = testConnectionOptions ?? getConnectionOptions(dbType); - let loggingOption: LoggerOptions = (await GenericHelpers.getConfigValue( - 'database.logging.enabled', - )) as boolean; + let loggingOption: LoggerOptions = config.getEnv('database.logging.enabled'); if (loggingOption) { - const optionsString = ( - (await GenericHelpers.getConfigValue('database.logging.options')) as string - ).replace(/\s+/g, ''); + const optionsString = config.getEnv('database.logging.options').replace(/\s+/g, ''); if (optionsString === 'all') { loggingOption = optionsString; @@ -112,9 +103,7 @@ export async function init( } } - const maxQueryExecutionTime = (await GenericHelpers.getConfigValue( - 'database.logging.maxQueryExecutionTime', - )) as string; + const maxQueryExecutionTime = config.getEnv('database.logging.maxQueryExecutionTime'); Object.assign(connectionOptions, { entities: Object.values(entities), diff --git a/packages/cli/src/GenericHelpers.ts b/packages/cli/src/GenericHelpers.ts index 90810af1a57ea..e3940a620b7c3 100644 --- a/packages/cli/src/GenericHelpers.ts +++ b/packages/cli/src/GenericHelpers.ts @@ -5,22 +5,19 @@ /* eslint-disable no-underscore-dangle */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import type express from 'express'; -import { readFile as fsReadFile } from 'fs/promises'; import type { ExecutionError, - IDataObject, INode, IRunExecutionData, Workflow, WorkflowExecuteMode, } from 'n8n-workflow'; import { validate } from 'class-validator'; +import { Like } from 'typeorm'; import config from '@/config'; import * as Db from '@/Db'; import type { ICredentialsDb, IExecutionDb, IExecutionFlattedDb, IWorkflowDb } from '@/Interfaces'; import * as ResponseHelper from '@/ResponseHelper'; -// eslint-disable-next-line import/order -import { Like } from 'typeorm'; import type { WorkflowEntity } from '@db/entities/WorkflowEntity'; import type { CredentialsEntity } from '@db/entities/CredentialsEntity'; import type { TagEntity } from '@db/entities/TagEntity'; @@ -28,7 +25,6 @@ import type { User } from '@db/entities/User'; /** * Returns the base URL n8n is reachable from - * */ export function getBaseUrl(): string { const protocol = config.getEnv('protocol'); @@ -44,73 +40,11 @@ export function getBaseUrl(): string { /** * Returns the session id if one is set - * */ export function getSessionId(req: express.Request): string | undefined { return req.headers.sessionid as string | undefined; } -/** - * Extracts configuration schema for key - */ -function extractSchemaForKey(configKey: string, configSchema: IDataObject): IDataObject { - const configKeyParts = configKey.split('.'); - - // eslint-disable-next-line no-restricted-syntax - for (const key of configKeyParts) { - if (configSchema[key] === undefined) { - throw new Error(`Key "${key}" of ConfigKey "${configKey}" does not exist`); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - } else if ((configSchema[key]! as IDataObject)._cvtProperties === undefined) { - configSchema = configSchema[key] as IDataObject; - } else { - configSchema = (configSchema[key] as IDataObject)._cvtProperties as IDataObject; - } - } - return configSchema; -} - -/** - * Gets value from config with support for "_FILE" environment variables - * - * @param {string} configKey The key of the config data to get - */ -export async function getConfigValue( - configKey: string, -): Promise { - // Get the environment variable - const configSchema = config.getSchema(); - // @ts-ignore - const currentSchema = extractSchemaForKey(configKey, configSchema._cvtProperties as IDataObject); - // Check if environment variable is defined for config key - if (currentSchema.env === undefined) { - // No environment variable defined, so return value from config - // @ts-ignore - return config.getEnv(configKey); - } - - // Check if special file environment variable exists - const fileEnvironmentVariable = process.env[`${currentSchema.env}_FILE`]; - if (fileEnvironmentVariable === undefined) { - // Does not exist, so return value from config - // @ts-ignore - return config.getEnv(configKey); - } - - let data; - try { - data = await fsReadFile(fileEnvironmentVariable, 'utf8'); - } catch (error) { - if (error.code === 'ENOENT') { - throw new Error(`The file "${fileEnvironmentVariable}" could not be found.`); - } - - throw error; - } - - return data; -} - /** * Generate a unique name for a workflow or credentials entity. * diff --git a/packages/cli/src/PublicApi/index.ts b/packages/cli/src/PublicApi/index.ts index 26f9757a21776..d7054d892953b 100644 --- a/packages/cli/src/PublicApi/index.ts +++ b/packages/cli/src/PublicApi/index.ts @@ -49,6 +49,10 @@ async function createApiRouter( ); } + apiController.get(`/${publicApiEndpoint}/${version}/openapi.yml`, (req, res) => { + res.sendFile(openApiSpecPath); + }); + apiController.use( `/${publicApiEndpoint}/${version}`, express.json(), diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index 257d6e2045052..37875490feb03 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -409,23 +409,17 @@ class Server extends AbstractServer { // Check for basic auth credentials if activated const basicAuthActive = config.getEnv('security.basicAuth.active'); if (basicAuthActive) { - const basicAuthUser = (await GenericHelpers.getConfigValue( - 'security.basicAuth.user', - )) as string; + const basicAuthUser = config.getEnv('security.basicAuth.user'); if (basicAuthUser === '') { throw new Error('Basic auth is activated but no user got defined. Please set one!'); } - const basicAuthPassword = (await GenericHelpers.getConfigValue( - 'security.basicAuth.password', - )) as string; + const basicAuthPassword = config.getEnv('security.basicAuth.password'); if (basicAuthPassword === '') { throw new Error('Basic auth is activated but no password got defined. Please set one!'); } - const basicAuthHashEnabled = (await GenericHelpers.getConfigValue( - 'security.basicAuth.hash', - )) as boolean; + const basicAuthHashEnabled = config.getEnv('security.basicAuth.hash') as boolean; let validPassword: null | string = null; @@ -483,31 +477,19 @@ class Server extends AbstractServer { // Check for and validate JWT if configured const jwtAuthActive = config.getEnv('security.jwtAuth.active'); if (jwtAuthActive) { - const jwtAuthHeader = (await GenericHelpers.getConfigValue( - 'security.jwtAuth.jwtHeader', - )) as string; + const jwtAuthHeader = config.getEnv('security.jwtAuth.jwtHeader'); if (jwtAuthHeader === '') { throw new Error('JWT auth is activated but no request header was defined. Please set one!'); } - const jwksUri = (await GenericHelpers.getConfigValue('security.jwtAuth.jwksUri')) as string; + const jwksUri = config.getEnv('security.jwtAuth.jwksUri'); if (jwksUri === '') { throw new Error('JWT auth is activated but no JWK Set URI was defined. Please set one!'); } - const jwtHeaderValuePrefix = (await GenericHelpers.getConfigValue( - 'security.jwtAuth.jwtHeaderValuePrefix', - )) as string; - const jwtIssuer = (await GenericHelpers.getConfigValue( - 'security.jwtAuth.jwtIssuer', - )) as string; - const jwtNamespace = (await GenericHelpers.getConfigValue( - 'security.jwtAuth.jwtNamespace', - )) as string; - const jwtAllowedTenantKey = (await GenericHelpers.getConfigValue( - 'security.jwtAuth.jwtAllowedTenantKey', - )) as string; - const jwtAllowedTenant = (await GenericHelpers.getConfigValue( - 'security.jwtAuth.jwtAllowedTenant', - )) as string; + const jwtHeaderValuePrefix = config.getEnv('security.jwtAuth.jwtHeaderValuePrefix'); + const jwtIssuer = config.getEnv('security.jwtAuth.jwtIssuer'); + const jwtNamespace = config.getEnv('security.jwtAuth.jwtNamespace'); + const jwtAllowedTenantKey = config.getEnv('security.jwtAuth.jwtAllowedTenantKey'); + const jwtAllowedTenant = config.getEnv('security.jwtAuth.jwtAllowedTenant'); // eslint-disable-next-line no-inner-declarations function isTenantAllowed(decodedToken: object): boolean { @@ -1456,7 +1438,7 @@ export async function start(): Promise { const binaryDataConfig = config.getEnv('binaryDataManager'); const diagnosticInfo: IDiagnosticInfo = { basicAuthActive: config.getEnv('security.basicAuth.active'), - databaseType: (await GenericHelpers.getConfigValue('database.type')) as DatabaseType, + databaseType: config.getEnv('database.type'), disableProductionWebhooksOnMainProcess: config.getEnv( 'endpoints.disableProductionWebhooksOnMainProcess', ), diff --git a/packages/cli/src/UserManagement/email/UserManagementMailer.ts b/packages/cli/src/UserManagement/email/UserManagementMailer.ts index 67cc4ec6e28f6..2c9ef67198177 100644 --- a/packages/cli/src/UserManagement/email/UserManagementMailer.ts +++ b/packages/cli/src/UserManagement/email/UserManagementMailer.ts @@ -2,7 +2,6 @@ import { existsSync } from 'fs'; import { readFile } from 'fs/promises'; import Handlebars from 'handlebars'; import { join as pathJoin } from 'path'; -import * as GenericHelpers from '@/GenericHelpers'; import config from '@/config'; import type { InviteEmailData, @@ -23,9 +22,7 @@ async function getTemplate( ): Promise