fix(core): Inline config.js to index.html to prevent CF from caching it (#18945)

This commit is contained in:
Tomi Turtiainen
2025-09-02 09:58:12 +03:00
committed by GitHub
parent 35e4772210
commit 17ce65a529
9 changed files with 352 additions and 31 deletions

View File

@@ -16,7 +16,7 @@ import { z } from 'zod';
import { ActiveExecutions } from '@/active-executions';
import { ActiveWorkflowManager } from '@/active-workflow-manager';
import config from '@/config';
import { EDITOR_UI_DIST_DIR } from '@/constants';
import { EDITOR_UI_DIST_DIR, N8N_VERSION } from '@/constants';
import { FeatureNotLicensedError } from '@/errors/feature-not-licensed.error';
import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus';
import { EventService } from '@/events/event.service';
@@ -117,6 +117,31 @@ export class Start extends BaseCommand<z.infer<typeof flagsSchema>> {
await this.exitSuccessFully();
}
/**
* Generates meta tags with base64-encoded configuration values
* for REST endpoint path and Sentry config.
*/
private generateConfigTags() {
const frontendSentryConfig = JSON.stringify({
dsn: this.globalConfig.sentry.frontendDsn,
environment: process.env.ENVIRONMENT || 'development',
serverName: process.env.DEPLOYMENT_NAME,
release: `n8n@${N8N_VERSION}`,
});
const b64Encode = (value: string) => Buffer.from(value).toString('base64');
// Base64 encode the configuration values
const restEndpointEncoded = b64Encode(this.globalConfig.endpoints.rest);
const sentryConfigEncoded = b64Encode(frontendSentryConfig);
const configMetaTags = [
`<meta name="n8n:config:rest-endpoint" content="${restEndpointEncoded}">`,
`<meta name="n8n:config:sentry" content="${sentryConfigEncoded}">`,
].join('');
return configMetaTags;
}
private async generateStaticAssets() {
// Read the index file and replace the path placeholder
const n8nPath = this.globalConfig.path;
@@ -138,6 +163,7 @@ export class Start extends BaseCommand<z.infer<typeof flagsSchema>> {
await mkdir(path.dirname(destFile), { recursive: true });
const streams = [
createReadStream(filePath, 'utf-8'),
replaceStream('%CONFIG_TAGS%', this.generateConfigTags(), { ignoreCase: false }),
replaceStream('/{{BASE_PATH}}/', n8nPath, { ignoreCase: false }),
replaceStream('/%7B%7BBASE_PATH%7D%7D/', n8nPath, { ignoreCase: false }),
replaceStream('/%257B%257BBASE_PATH%257D%257D/', n8nPath, { ignoreCase: false }),

View File

@@ -1,4 +1,3 @@
import { CLI_DIR, EDITOR_UI_DIST_DIR, inE2ETests, N8N_VERSION } from '@/constants';
import { inDevelopment, inProduction } from '@n8n/backend-common';
import { SecurityConfig } from '@n8n/config';
import { Time } from '@n8n/constants';
@@ -15,6 +14,7 @@ import { resolve } from 'path';
import { AbstractServer } from '@/abstract-server';
import config from '@/config';
import { CLI_DIR, EDITOR_UI_DIST_DIR, inE2ETests } from '@/constants';
import { ControllerRegistry } from '@/controller.registry';
import { CredentialsOverwrites } from '@/credentials-overwrites';
import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus';
@@ -274,22 +274,6 @@ export class Server extends AbstractServer {
`/${this.restEndpoint}/settings`,
ResponseHelper.send(async () => frontendService.getSettings()),
);
this.app.get(`/${this.restEndpoint}/config.js`, (_req, res) => {
const frontendSentryConfig = JSON.stringify({
dsn: this.globalConfig.sentry.frontendDsn,
environment: process.env.ENVIRONMENT || 'development',
serverName: process.env.DEPLOYMENT_NAME,
release: `n8n@${N8N_VERSION}`,
});
const frontendConfig = [
`window.REST_ENDPOINT = '${this.globalConfig.endpoints.rest}';`,
`window.sentry = ${frontendSentryConfig};`,
].join('\n');
res.type('application/javascript');
res.send(frontendConfig);
});
}
// ----------------------------------------