Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editor): Block the frontend when trying to access n8n from another host over http #8906

Merged
merged 5 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/cli/src/services/frontend.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ export class FrontendService {
urlBaseEditor: instanceBaseUrl,
binaryDataMode: config.getEnv('binaryDataManager.mode'),
versionCli: '',
authCookie: {
secure: config.getEnv('secure_cookie'),
},
releaseChannel: config.getEnv('generic.releaseChannel'),
oauthCallbackUrls: {
oauth1: `${instanceBaseUrl}/${restEndpoint}/oauth1-credential/callback`,
Expand Down
110 changes: 109 additions & 1 deletion packages/editor-ui/src/__tests__/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { INodeTypeData, INodeTypeDescription } from 'n8n-workflow';
import type { INodeTypeData, INodeTypeDescription, IN8nUISettings } from 'n8n-workflow';
import { AGENT_NODE_TYPE, CHAT_TRIGGER_NODE_TYPE, MANUAL_TRIGGER_NODE_TYPE } from '@/constants';
import nodeTypesJson from '../../../nodes-base/dist/types/nodes.json';
import aiNodeTypesJson from '../../../@n8n/nodes-langchain/dist/types/nodes.json';
Expand Down Expand Up @@ -42,3 +42,111 @@ export function mockNodeTypesToArray(nodeTypes: INodeTypeData): INodeTypeDescrip

export const defaultMockNodeTypesArray: INodeTypeDescription[] =
mockNodeTypesToArray(defaultMockNodeTypes);

export const defaultSettings: IN8nUISettings = {
allowedModules: {},
communityNodesEnabled: false,
defaultLocale: '',
endpointForm: '',
endpointFormTest: '',
endpointFormWaiting: '',
endpointWebhook: '',
endpointWebhookTest: '',
enterprise: {
sharing: false,
ldap: false,
saml: false,
logStreaming: false,
debugInEditor: false,
advancedExecutionFilters: false,
variables: true,
sourceControl: false,
auditLogs: false,
showNonProdBanner: false,
workflowHistory: false,
binaryDataS3: false,
externalSecrets: false,
workerView: false,
advancedPermissions: false,
},
expressions: {
evaluator: 'tournament',
},
executionMode: 'regular',
executionTimeout: 0,
hideUsagePage: false,
hiringBannerEnabled: false,
instanceId: '',
isNpmAvailable: false,
license: { environment: 'development' },
logLevel: 'info',
maxExecutionTimeout: 0,
oauthCallbackUrls: { oauth1: '', oauth2: '' },
onboardingCallPromptEnabled: false,
personalizationSurveyEnabled: false,
releaseChannel: 'stable',
posthog: {
apiHost: '',
apiKey: '',
autocapture: false,
debug: false,
disableSessionRecording: false,
enabled: false,
},
publicApi: { enabled: false, latestVersion: 0, path: '', swaggerUi: { enabled: false } },
pushBackend: 'websocket',
saveDataErrorExecution: 'DEFAULT',
saveDataSuccessExecution: 'DEFAULT',
saveManualExecutions: false,
sso: {
ldap: { loginEnabled: false, loginLabel: '' },
saml: { loginEnabled: false, loginLabel: '' },
},
telemetry: {
enabled: false,
},
templates: { enabled: false, host: '' },
timezone: '',
urlBaseEditor: '',
urlBaseWebhook: '',
authCookie: {
secure: false,
},
userManagement: {
showSetupOnFirstLoad: false,
smtpSetup: true,
authenticationMethod: 'email',
quota: 10,
},
versionCli: '',
versionNotifications: {
enabled: true,
endpoint: '',
infoUrl: '',
},
workflowCallerPolicyDefaultOption: 'any',
workflowTagsDisabled: false,
variables: {
limit: -1,
},
deployment: {
type: 'default',
},
banners: {
dismissed: [],
},
binaryDataMode: 'default',
previewMode: false,
mfa: {
enabled: false,
},
ai: {
enabled: false,
provider: '',
errorDebugging: false,
},
workflowHistory: {
pruneTime: 0,
licensePruneTime: 0,
},
};
94 changes: 1 addition & 93 deletions packages/editor-ui/src/__tests__/server/endpoints/settings.ts
Original file line number Diff line number Diff line change
@@ -1,99 +1,7 @@
import type { Server } from 'miragejs';
import { Response } from 'miragejs';
import type { AppSchema } from '../types';
import type { IN8nUISettings } from 'n8n-workflow';

const defaultSettings: IN8nUISettings = {
allowedModules: {},
communityNodesEnabled: false,
defaultLocale: '',
endpointForm: '',
endpointFormTest: '',
endpointFormWaiting: '',
endpointWebhook: '',
endpointWebhookTest: '',
enterprise: {
sharing: false,
ldap: false,
saml: false,
logStreaming: false,
debugInEditor: false,
advancedExecutionFilters: false,
variables: true,
sourceControl: false,
auditLogs: false,
showNonProdBanner: false,
workflowHistory: false,
debugInEditor: false,
binaryDataS3: false,
externalSecrets: false,
workerView: false,
},
expressions: {
evaluator: 'tournament',
},
executionMode: 'regular',
executionTimeout: 0,
hideUsagePage: false,
hiringBannerEnabled: false,
instanceId: '',
isNpmAvailable: false,
license: { environment: 'development' },
logLevel: 'info',
maxExecutionTimeout: 0,
oauthCallbackUrls: { oauth1: '', oauth2: '' },
onboardingCallPromptEnabled: false,
personalizationSurveyEnabled: false,
releaseChannel: 'stable',
posthog: {
apiHost: '',
apiKey: '',
autocapture: false,
debug: false,
disableSessionRecording: false,
enabled: false,
},
publicApi: { enabled: false, latestVersion: 0, path: '', swaggerUi: { enabled: false } },
pushBackend: 'websocket',
releaseChannel: 'stable',
saveDataErrorExecution: 'DEFAULT',
saveDataSuccessExecution: 'DEFAULT',
saveManualExecutions: false,
sso: {
ldap: { loginEnabled: false, loginLabel: '' },
saml: { loginEnabled: false, loginLabel: '' },
},
telemetry: {
enabled: false,
},
templates: { enabled: false, host: '' },
timezone: '',
urlBaseEditor: '',
urlBaseWebhook: '',
userManagement: {
showSetupOnFirstLoad: false,
smtpSetup: true,
authenticationMethod: 'email',
},
versionCli: '',
versionNotifications: {
enabled: true,
endpoint: '',
infoUrl: '',
},
workflowCallerPolicyDefaultOption: 'any',
workflowTagsDisabled: false,
variables: {
limit: -1,
},
deployment: {
type: 'default',
},
banners: {
dismissed: [],
},
binaryDataMode: 'default',
};
import { defaultSettings } from '../../defaults';

export function routesForSettings(server: Server) {
server.get('/rest/settings', (schema: AppSchema) => {
Expand Down
90 changes: 3 additions & 87 deletions packages/editor-ui/src/__tests__/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ISettingsState } from '@/Interface';
import { UserManagementAuthenticationMethod } from '@/Interface';
import { defaultSettings } from './defaults';

export const retry = async (
assertion: () => ReturnType<typeof expect>,
Expand All @@ -25,103 +26,18 @@ export const retry = async (
export const waitAllPromises = async () => await new Promise((resolve) => setTimeout(resolve));

export const SETTINGS_STORE_DEFAULT_STATE: ISettingsState = {
settings: {
allowedModules: {},
communityNodesEnabled: false,
defaultLocale: '',
endpointForm: '',
endpointFormTest: '',
endpointFormWaiting: '',
endpointWebhook: '',
endpointWebhookTest: '',
enterprise: {
advancedExecutionFilters: false,
sharing: false,
ldap: false,
saml: false,
logStreaming: false,
variables: false,
sourceControl: false,
auditLogs: false,
},
executionMode: 'regular',
executionTimeout: 0,
hideUsagePage: false,
hiringBannerEnabled: false,
instanceId: '',
isNpmAvailable: false,
license: { environment: 'production' },
logLevel: 'info',
maxExecutionTimeout: 0,
oauthCallbackUrls: { oauth1: '', oauth2: '' },
onboardingCallPromptEnabled: false,
personalizationSurveyEnabled: false,
posthog: {
apiHost: '',
apiKey: '',
autocapture: false,
debug: false,
disableSessionRecording: false,
enabled: false,
},
publicApi: { enabled: false, latestVersion: 0, path: '', swaggerUi: { enabled: false } },
pushBackend: 'sse',
saveDataErrorExecution: 'all',
saveDataSuccessExecution: 'all',
saveManualExecutions: false,
sso: {
ldap: { loginEnabled: false, loginLabel: '' },
saml: { loginEnabled: false, loginLabel: '' },
},
telemetry: { enabled: false },
templates: { enabled: false, host: '' },
timezone: '',
urlBaseEditor: '',
urlBaseWebhook: '',
userManagement: {
enabled: false,
smtpSetup: false,
authenticationMethod: UserManagementAuthenticationMethod.Email,
},
versionCli: '',
versionNotifications: {
enabled: false,
endpoint: '',
infoUrl: '',
},
workflowCallerPolicyDefaultOption: 'any',
workflowTagsDisabled: false,
deployment: {
type: 'default',
},
variables: {
limit: 100,
},
expressions: {
evaluator: 'tournament',
},
banners: {
dismissed: [],
},
ai: {
enabled: false,
},
workflowHistory: {
pruneTime: -1,
licensePruneTime: -1,
},
},
settings: defaultSettings,
promptsData: {
message: '',
title: '',
showContactPrompt: false,
showValueSurvey: false,
},
userManagement: {
enabled: false,
showSetupOnFirstLoad: false,
smtpSetup: false,
authenticationMethod: UserManagementAuthenticationMethod.Email,
quota: defaultSettings.userManagement.quota,
},
templatesEndpointHealthy: false,
api: {
Expand Down
16 changes: 16 additions & 0 deletions packages/editor-ui/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -759,3 +759,19 @@ export const ROLE = {
Admin: 'global:admin',
Default: 'default', // default user with no email when setting up instance
} as const;

export const INSECURE_CONNECTION_WARNING = `
<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 visiting this via an insecure URL
</h2>
<br/>
<div style="font-size: 18px; max-width: 640px; text-align: left; margin: 10px auto">
To fix this, please consider the following options:
<ul>
<li>Setup TLS/HTTPS (<strong>recommended</strong>), or</li>
<li>If you are running this locally, 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>
</ul>
</div>
</body>`;
2 changes: 2 additions & 0 deletions packages/editor-ui/src/stores/__tests__/posthog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useTelemetryStore } from '@/stores/telemetry.store';
import type { IN8nUISettings } from 'n8n-workflow';
import { LOCAL_STORAGE_EXPERIMENT_OVERRIDES } from '@/constants';
import { nextTick } from 'vue';
import { defaultSettings } from '../../__tests__/defaults';

const DEFAULT_POSTHOG_SETTINGS: IN8nUISettings['posthog'] = {
enabled: true,
Expand All @@ -21,6 +22,7 @@ const CURRENT_INSTANCE_ID = '456';

function setSettings(overrides?: Partial<IN8nUISettings>) {
useSettingsStore().setSettings({
...defaultSettings,
posthog: DEFAULT_POSTHOG_SETTINGS,
instanceId: CURRENT_INSTANCE_ID,
...overrides,
Expand Down
Loading
Loading