feat(editor): Localize insecure connection warning (no-changelog) (#34636)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Alex Grozav
2026-07-22 08:39:33 +00:00
committed by GitHub
co-authored by Claude Opus 4.8
parent db5c59f9e5
commit 8301a804b4
5 changed files with 71 additions and 8 deletions
@@ -3072,6 +3072,11 @@
"saveButton.saved": "Saved",
"saveButton.saving": "Saving",
"settings": "Settings",
"settings.authCookie.insecureConnection.title": "Your n8n server is configured to use a secure cookie, however you are either visiting this via an insecure URL, or using Safari.",
"settings.authCookie.insecureConnection.fixIntro": "To fix this, please consider the following options:",
"settings.authCookie.insecureConnection.option.tls": "Setup TLS/HTTPS (<strong>recommended</strong>), or",
"settings.authCookie.insecureConnection.option.localhost": "If you are running this locally, and not using Safari, try using <a href=\"{localhostUrl}\">localhost</a> instead",
"settings.authCookie.insecureConnection.option.disableSecureCookie": "If you prefer to disable this security feature (<strong>not recommended</strong>), set the environment variable <code>{envVar}</code> to <code>false</code>",
"settings.communityNodes": "Community nodes",
"settings.communityNodes.empty.title": "Supercharge your workflows with community nodes",
"settings.communityNodes.empty.verified.only.title": "Supercharge your workflows with verified community nodes",
@@ -37,6 +37,7 @@
},
"dependencies": {
"@n8n/api-types": "workspace:*",
"@n8n/i18n": "workspace:*",
"@n8n/permissions": "workspace:*",
"@n8n/rest-api-client": "workspace:*",
"n8n-workflow": "workspace:*",
@@ -1,5 +1,7 @@
import type { FrontendSettings } from '@n8n/api-types';
import { i18n } from '@n8n/i18n';
import { createPinia, setActivePinia } from 'pinia';
import type { MockInstance } from 'vitest';
import { mock } from 'vitest-mock-extended';
import { useSettingsStore } from './settings.store';
@@ -167,6 +169,56 @@ describe('settings.store', () => {
});
});
describe('insecure connection warning', () => {
let writeSpy: MockInstance<(...text: string[]) => void>;
beforeEach(() => {
writeSpy = vi.spyOn(document, 'write').mockImplementation(() => {});
});
afterEach(() => {
vi.unstubAllGlobals();
});
it('should render the localized warning over an insecure, non-localhost origin', async () => {
vi.stubGlobal('location', { protocol: 'http:', hostname: 'n8n.example.com' });
getSettings.mockResolvedValueOnce({ ...mockSettings, authCookie: { secure: true } });
await useSettingsStore().getSettings();
expect(writeSpy).toHaveBeenCalledTimes(1);
const markup = writeSpy.mock.calls[0][0];
expect(markup).toContain(i18n.baseText('settings.authCookie.insecureConnection.title'));
expect(markup).toContain('N8N_SECURE_COOKIE');
expect(markup).toContain('http://localhost:5678');
});
it('should not render the warning over localhost in a non-Safari browser', async () => {
vi.stubGlobal('location', { protocol: 'http:', hostname: 'localhost' });
vi.stubGlobal('navigator', {
userAgent:
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0',
});
getSettings.mockResolvedValueOnce({ ...mockSettings, authCookie: { secure: true } });
await useSettingsStore().getSettings();
expect(writeSpy).not.toHaveBeenCalled();
});
it('should not render the warning when the cookie is not secure', async () => {
vi.stubGlobal('location', { protocol: 'http:', hostname: 'n8n.example.com' });
getSettings.mockResolvedValueOnce({ ...mockSettings, authCookie: { secure: false } });
await useSettingsStore().getSettings();
expect(writeSpy).not.toHaveBeenCalled();
});
});
describe('getSettings', () => {
describe('telemetry', () => {
it('should fetch settings and call sessionStarted if telemetry is enabled', async () => {
@@ -5,6 +5,7 @@ import {
type FrontendModuleSettings,
type WorkflowReviewsPolicy,
} from '@n8n/api-types';
import { i18n } from '@n8n/i18n';
import { makeRestApiRequest } from '@n8n/rest-api-client';
import * as aiUsageApi from '@n8n/rest-api-client/api/ai-usage';
import * as eventsApi from '@n8n/rest-api-client/api/events';
@@ -22,19 +23,20 @@ import { useRootStore } from './useRootStore';
/**
* Full-page warning rendered when the instance requires a secure cookie but the
* page is served over an insecure origin (or via Safari, which drops the cookie).
* The copy is localized; the structural markup and inline styles stay in code
* because this is written via `document.write` before the Vue app mounts.
*/
const INSECURE_CONNECTION_WARNING = `
const buildInsecureConnectionWarning = () => `
<body style="margin-top: 20px; font-family: 'Open Sans', sans-serif; text-align: center;">
<h1 style="font-size: 40px">&#x1F6AB;</h1>
<h2>Your n8n server is configured to use a secure cookie, <br/>however you are either visiting this via an insecure URL, or using Safari.
</h2>
<h2>${i18n.baseText('settings.authCookie.insecureConnection.title')}</h2>
<br/>
<div style="font-size: 18px; max-width: 640px; text-align: left; margin: 10px auto">
To fix this, please consider the following options:
${i18n.baseText('settings.authCookie.insecureConnection.fixIntro')}
<ul>
<li>Setup TLS/HTTPS (<strong>recommended</strong>), or</li>
<li>If you are running this locally, and not using Safari, try using <a href="http://localhost:5678">localhost</a> instead</li>
<li>If you prefer to disable this security feature (<strong>not recommended</strong>), set the environment variable <code>N8N_SECURE_COOKIE</code> to <code>false</code></li>
<li>${i18n.baseText('settings.authCookie.insecureConnection.option.tls')}</li>
<li>${i18n.baseText('settings.authCookie.insecureConnection.option.localhost', { interpolate: { localhostUrl: 'http://localhost:5678' } })}</li>
<li>${i18n.baseText('settings.authCookie.insecureConnection.option.disableSecureCookie', { interpolate: { envVar: 'N8N_SECURE_COOKIE' } })}</li>
</ul>
</div>
</body>`;
@@ -290,7 +292,7 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, () => {
location.protocol === 'http:' &&
(!['localhost', '127.0.0.1'].includes(location.hostname) || browser.name === 'Safari')
) {
document.write(INSECURE_CONNECTION_WARNING);
document.write(buildInsecureConnectionWarning());
return;
}
}
+3
View File
@@ -5383,6 +5383,9 @@ importers:
'@n8n/api-types':
specifier: workspace:*
version: link:../../../@n8n/api-types
'@n8n/i18n':
specifier: workspace:*
version: link:../i18n
'@n8n/permissions':
specifier: workspace:*
version: link:../../../@n8n/permissions