mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 20:24:05 -08:00
feat: Introduce debug info button (#9895)
This commit is contained in:
parent
ae67d6b753
commit
be9a247577
|
@ -338,6 +338,10 @@ export class License {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getConsumerId() {
|
||||||
|
return this.manager?.getConsumerId() ?? 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
// Helper functions for computed data
|
// Helper functions for computed data
|
||||||
getUsersLimit() {
|
getUsersLimit() {
|
||||||
return this.getFeatureValue(LICENSE_QUOTAS.USERS_LIMIT) ?? UNLIMITED_LICENSE_QUOTA;
|
return this.getFeatureValue(LICENSE_QUOTAS.USERS_LIMIT) ?? UNLIMITED_LICENSE_QUOTA;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import fs from 'node:fs';
|
||||||
import { Container, Service } from 'typedi';
|
import { Container, Service } from 'typedi';
|
||||||
import uniq from 'lodash/uniq';
|
import uniq from 'lodash/uniq';
|
||||||
import { createWriteStream } from 'fs';
|
import { createWriteStream } from 'fs';
|
||||||
|
@ -83,6 +84,8 @@ export class FrontendService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.settings = {
|
this.settings = {
|
||||||
|
isDocker: this.isDocker(),
|
||||||
|
databaseType: config.getEnv('database.type'),
|
||||||
previewMode: process.env.N8N_PREVIEW_MODE === 'true',
|
previewMode: process.env.N8N_PREVIEW_MODE === 'true',
|
||||||
endpointForm: config.getEnv('endpoints.form'),
|
endpointForm: config.getEnv('endpoints.form'),
|
||||||
endpointFormTest: config.getEnv('endpoints.formTest'),
|
endpointFormTest: config.getEnv('endpoints.formTest'),
|
||||||
|
@ -92,6 +95,7 @@ export class FrontendService {
|
||||||
saveDataErrorExecution: config.getEnv('executions.saveDataOnError'),
|
saveDataErrorExecution: config.getEnv('executions.saveDataOnError'),
|
||||||
saveDataSuccessExecution: config.getEnv('executions.saveDataOnSuccess'),
|
saveDataSuccessExecution: config.getEnv('executions.saveDataOnSuccess'),
|
||||||
saveManualExecutions: config.getEnv('executions.saveDataManualExecutions'),
|
saveManualExecutions: config.getEnv('executions.saveDataManualExecutions'),
|
||||||
|
saveExecutionProgress: config.getEnv('executions.saveExecutionProgress'),
|
||||||
executionTimeout: config.getEnv('executions.timeout'),
|
executionTimeout: config.getEnv('executions.timeout'),
|
||||||
maxExecutionTimeout: config.getEnv('executions.maxTimeout'),
|
maxExecutionTimeout: config.getEnv('executions.maxTimeout'),
|
||||||
workflowCallerPolicyDefaultOption: config.getEnv('workflows.callerPolicyDefaultOption'),
|
workflowCallerPolicyDefaultOption: config.getEnv('workflows.callerPolicyDefaultOption'),
|
||||||
|
@ -99,7 +103,9 @@ export class FrontendService {
|
||||||
urlBaseWebhook: this.urlService.getWebhookBaseUrl(),
|
urlBaseWebhook: this.urlService.getWebhookBaseUrl(),
|
||||||
urlBaseEditor: instanceBaseUrl,
|
urlBaseEditor: instanceBaseUrl,
|
||||||
binaryDataMode: config.getEnv('binaryDataManager.mode'),
|
binaryDataMode: config.getEnv('binaryDataManager.mode'),
|
||||||
|
nodeJsVersion: process.version.replace(/^v/, ''),
|
||||||
versionCli: '',
|
versionCli: '',
|
||||||
|
concurrency: config.getEnv('executions.concurrency.productionLimit'),
|
||||||
authCookie: {
|
authCookie: {
|
||||||
secure: config.getEnv('secure_cookie'),
|
secure: config.getEnv('secure_cookie'),
|
||||||
},
|
},
|
||||||
|
@ -196,6 +202,7 @@ export class FrontendService {
|
||||||
},
|
},
|
||||||
hideUsagePage: config.getEnv('hideUsagePage'),
|
hideUsagePage: config.getEnv('hideUsagePage'),
|
||||||
license: {
|
license: {
|
||||||
|
consumerId: 'unknown',
|
||||||
environment: config.getEnv('license.tenantId') === 1 ? 'production' : 'staging',
|
environment: config.getEnv('license.tenantId') === 1 ? 'production' : 'staging',
|
||||||
},
|
},
|
||||||
variables: {
|
variables: {
|
||||||
|
@ -218,6 +225,14 @@ export class FrontendService {
|
||||||
pruneTime: -1,
|
pruneTime: -1,
|
||||||
licensePruneTime: -1,
|
licensePruneTime: -1,
|
||||||
},
|
},
|
||||||
|
pruning: {
|
||||||
|
isEnabled: config.getEnv('executions.pruneData'),
|
||||||
|
maxAge: config.getEnv('executions.pruneDataMaxAge'),
|
||||||
|
maxCount: config.getEnv('executions.pruneDataMaxCount'),
|
||||||
|
},
|
||||||
|
security: {
|
||||||
|
blockFileAccessToN8nFiles: config.getEnv('security.blockFileAccessToN8nFiles'),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +284,9 @@ export class FrontendService {
|
||||||
const isS3Available = config.getEnv('binaryDataManager.availableModes').includes('s3');
|
const isS3Available = config.getEnv('binaryDataManager.availableModes').includes('s3');
|
||||||
const isS3Licensed = this.license.isBinaryDataS3Licensed();
|
const isS3Licensed = this.license.isBinaryDataS3Licensed();
|
||||||
|
|
||||||
|
this.settings.license.planName = this.license.getPlanName();
|
||||||
|
this.settings.license.consumerId = this.license.getConsumerId();
|
||||||
|
|
||||||
// refresh enterprise status
|
// refresh enterprise status
|
||||||
Object.assign(this.settings.enterprise, {
|
Object.assign(this.settings.enterprise, {
|
||||||
sharing: this.license.isSharingEnabled(),
|
sharing: this.license.isSharingEnabled(),
|
||||||
|
@ -368,4 +386,20 @@ export class FrontendService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this instance is running inside a Docker container.
|
||||||
|
*
|
||||||
|
* Based on: https://github.com/sindresorhus/is-docker
|
||||||
|
*/
|
||||||
|
private isDocker() {
|
||||||
|
try {
|
||||||
|
return (
|
||||||
|
fs.existsSync('/.dockerenv') ||
|
||||||
|
fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker')
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1123,7 +1123,7 @@ export interface RootState {
|
||||||
urlBaseEditor: string;
|
urlBaseEditor: string;
|
||||||
instanceId: string;
|
instanceId: string;
|
||||||
isNpmAvailable: boolean;
|
isNpmAvailable: boolean;
|
||||||
binaryDataMode: string;
|
binaryDataMode: 'default' | 'filesystem' | 's3';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NodeMetadataMap {
|
export interface NodeMetadataMap {
|
||||||
|
@ -1380,9 +1380,10 @@ export interface ISettingsState {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
};
|
};
|
||||||
onboardingCallPromptEnabled: boolean;
|
onboardingCallPromptEnabled: boolean;
|
||||||
saveDataErrorExecution: string;
|
saveDataErrorExecution: WorkflowSettings.SaveDataExecution;
|
||||||
saveDataSuccessExecution: string;
|
saveDataSuccessExecution: WorkflowSettings.SaveDataExecution;
|
||||||
saveManualExecutions: boolean;
|
saveManualExecutions: boolean;
|
||||||
|
saveDataProgressExecution: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type NodeTypesByTypeNameAndVersion = {
|
export type NodeTypesByTypeNameAndVersion = {
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
import type { IN8nUISettings } from 'n8n-workflow';
|
import type { IN8nUISettings } from 'n8n-workflow';
|
||||||
|
|
||||||
export const defaultSettings: IN8nUISettings = {
|
export const defaultSettings: IN8nUISettings = {
|
||||||
|
databaseType: 'sqlite',
|
||||||
|
isDocker: false,
|
||||||
|
pruning: {
|
||||||
|
isEnabled: false,
|
||||||
|
maxAge: 0,
|
||||||
|
maxCount: 0,
|
||||||
|
},
|
||||||
allowedModules: {},
|
allowedModules: {},
|
||||||
communityNodesEnabled: false,
|
communityNodesEnabled: false,
|
||||||
defaultLocale: '',
|
defaultLocale: '',
|
||||||
|
@ -40,7 +47,7 @@ export const defaultSettings: IN8nUISettings = {
|
||||||
hiringBannerEnabled: false,
|
hiringBannerEnabled: false,
|
||||||
instanceId: '',
|
instanceId: '',
|
||||||
isNpmAvailable: false,
|
isNpmAvailable: false,
|
||||||
license: { environment: 'development' },
|
license: { environment: 'development', consumerId: 'unknown' },
|
||||||
logLevel: 'info',
|
logLevel: 'info',
|
||||||
maxExecutionTimeout: 0,
|
maxExecutionTimeout: 0,
|
||||||
oauthCallbackUrls: { oauth1: '', oauth2: '' },
|
oauthCallbackUrls: { oauth1: '', oauth2: '' },
|
||||||
|
@ -60,6 +67,7 @@ export const defaultSettings: IN8nUISettings = {
|
||||||
saveDataErrorExecution: 'DEFAULT',
|
saveDataErrorExecution: 'DEFAULT',
|
||||||
saveDataSuccessExecution: 'DEFAULT',
|
saveDataSuccessExecution: 'DEFAULT',
|
||||||
saveManualExecutions: false,
|
saveManualExecutions: false,
|
||||||
|
saveExecutionProgress: false,
|
||||||
sso: {
|
sso: {
|
||||||
ldap: { loginEnabled: false, loginLabel: '' },
|
ldap: { loginEnabled: false, loginLabel: '' },
|
||||||
saml: { loginEnabled: false, loginLabel: '' },
|
saml: { loginEnabled: false, loginLabel: '' },
|
||||||
|
@ -81,6 +89,8 @@ export const defaultSettings: IN8nUISettings = {
|
||||||
quota: 10,
|
quota: 10,
|
||||||
},
|
},
|
||||||
versionCli: '',
|
versionCli: '',
|
||||||
|
nodeJsVersion: '',
|
||||||
|
concurrency: -1,
|
||||||
versionNotifications: {
|
versionNotifications: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
endpoint: '',
|
endpoint: '',
|
||||||
|
@ -113,4 +123,7 @@ export const defaultSettings: IN8nUISettings = {
|
||||||
pruneTime: 0,
|
pruneTime: 0,
|
||||||
licensePruneTime: 0,
|
licensePruneTime: 0,
|
||||||
},
|
},
|
||||||
|
security: {
|
||||||
|
blockFileAccessToN8nFiles: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -68,6 +68,7 @@ export const SETTINGS_STORE_DEFAULT_STATE: ISettingsState = {
|
||||||
onboardingCallPromptEnabled: false,
|
onboardingCallPromptEnabled: false,
|
||||||
saveDataErrorExecution: 'all',
|
saveDataErrorExecution: 'all',
|
||||||
saveDataSuccessExecution: 'all',
|
saveDataSuccessExecution: 'all',
|
||||||
|
saveDataProgressExecution: false,
|
||||||
saveManualExecutions: false,
|
saveManualExecutions: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,16 @@
|
||||||
<n8n-text>{{ rootStore.instanceId }}</n8n-text>
|
<n8n-text>{{ rootStore.instanceId }}</n8n-text>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8" class="info-name">
|
||||||
|
<n8n-text>{{ $locale.baseText('about.debug.title') }}</n8n-text>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<div :class="$style.debugInfo" @click="copyDebugInfoToClipboard">
|
||||||
|
<n8n-link>{{ $locale.baseText('about.debug.message') }}</n8n-link>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -66,6 +76,9 @@ import Modal from './Modal.vue';
|
||||||
import { ABOUT_MODAL_KEY } from '../constants';
|
import { ABOUT_MODAL_KEY } from '../constants';
|
||||||
import { useSettingsStore } from '@/stores/settings.store';
|
import { useSettingsStore } from '@/stores/settings.store';
|
||||||
import { useRootStore } from '@/stores/root.store';
|
import { useRootStore } from '@/stores/root.store';
|
||||||
|
import { useToast } from '@/composables/useToast';
|
||||||
|
import { useClipboard } from '@/composables/useClipboard';
|
||||||
|
import { useDebugInfo } from '@/composables/useDebugInfo';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'About',
|
name: 'About',
|
||||||
|
@ -85,6 +98,15 @@ export default defineComponent({
|
||||||
closeDialog() {
|
closeDialog() {
|
||||||
this.modalBus.emit('close');
|
this.modalBus.emit('close');
|
||||||
},
|
},
|
||||||
|
async copyDebugInfoToClipboard() {
|
||||||
|
useToast().showToast({
|
||||||
|
title: this.$locale.baseText('about.debug.toast.title'),
|
||||||
|
message: this.$locale.baseText('about.debug.toast.message'),
|
||||||
|
type: 'info',
|
||||||
|
duration: 5000,
|
||||||
|
});
|
||||||
|
await useClipboard().copy(useDebugInfo().generateDebugInfo());
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
148
packages/editor-ui/src/composables/useDebugInfo.ts
Normal file
148
packages/editor-ui/src/composables/useDebugInfo.ts
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
import { useSettingsStore } from '@/stores/settings.store';
|
||||||
|
import type { WorkflowSettings } from 'n8n-workflow';
|
||||||
|
|
||||||
|
type DebugInfo = {
|
||||||
|
core: {
|
||||||
|
n8nVersion: string;
|
||||||
|
platform: 'docker (cloud)' | 'docker (self-hosted)' | 'npm';
|
||||||
|
nodeJsVersion: string;
|
||||||
|
database: 'sqlite' | 'mysql' | 'mariadb' | 'postgres';
|
||||||
|
executionMode: 'regular' | 'scaling';
|
||||||
|
license: 'community' | 'enterprise (production)' | 'enterprise (sandbox)';
|
||||||
|
consumerId: string;
|
||||||
|
concurrency: number;
|
||||||
|
};
|
||||||
|
storage: {
|
||||||
|
success: WorkflowSettings.SaveDataExecution;
|
||||||
|
error: WorkflowSettings.SaveDataExecution;
|
||||||
|
progress: boolean;
|
||||||
|
manual: boolean;
|
||||||
|
binaryMode: 'memory' | 'filesystem' | 's3';
|
||||||
|
};
|
||||||
|
pruning:
|
||||||
|
| {
|
||||||
|
enabled: false;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
enabled: true;
|
||||||
|
maxAge: `${number} hours`;
|
||||||
|
maxCount: `${number} executions`;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Reported only if insecure settings are found.
|
||||||
|
*/
|
||||||
|
security?: {
|
||||||
|
secureCookie?: boolean;
|
||||||
|
blockFileAccessToN8nFiles?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useDebugInfo() {
|
||||||
|
const store = useSettingsStore();
|
||||||
|
|
||||||
|
const coreInfo = () => {
|
||||||
|
return {
|
||||||
|
n8nVersion: store.versionCli,
|
||||||
|
platform:
|
||||||
|
store.isDocker && store.deploymentType === 'cloud'
|
||||||
|
? 'docker (cloud)'
|
||||||
|
: store.isDocker
|
||||||
|
? 'docker (self-hosted)'
|
||||||
|
: 'npm',
|
||||||
|
nodeJsVersion: store.nodeJsVersion,
|
||||||
|
database:
|
||||||
|
store.databaseType === 'postgresdb'
|
||||||
|
? 'postgres'
|
||||||
|
: store.databaseType === 'mysqldb'
|
||||||
|
? 'mysql'
|
||||||
|
: store.databaseType,
|
||||||
|
executionMode: store.isQueueModeEnabled ? 'scaling' : 'regular',
|
||||||
|
concurrency: store.settings.concurrency,
|
||||||
|
license:
|
||||||
|
store.planName === 'Community'
|
||||||
|
? (store.planName.toLowerCase() as 'community')
|
||||||
|
: store.settings.license.environment === 'production'
|
||||||
|
? 'enterprise (production)'
|
||||||
|
: 'enterprise (sandbox)',
|
||||||
|
consumerId: store.consumerId,
|
||||||
|
} as const;
|
||||||
|
};
|
||||||
|
|
||||||
|
const storageInfo = (): DebugInfo['storage'] => {
|
||||||
|
return {
|
||||||
|
success: store.saveDataSuccessExecution,
|
||||||
|
error: store.saveDataErrorExecution,
|
||||||
|
progress: store.saveDataProgressExecution,
|
||||||
|
manual: store.saveManualExecutions,
|
||||||
|
binaryMode: store.binaryDataMode === 'default' ? 'memory' : store.binaryDataMode,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const pruningInfo = () => {
|
||||||
|
if (!store.pruning.isEnabled) return { enabled: false } as const;
|
||||||
|
|
||||||
|
return {
|
||||||
|
enabled: true,
|
||||||
|
maxAge: `${store.pruning.maxAge} hours`,
|
||||||
|
maxCount: `${store.pruning.maxCount} executions`,
|
||||||
|
} as const;
|
||||||
|
};
|
||||||
|
|
||||||
|
const securityInfo = () => {
|
||||||
|
const info: DebugInfo['security'] = {};
|
||||||
|
|
||||||
|
if (!store.security.blockFileAccessToN8nFiles) info.blockFileAccessToN8nFiles = false;
|
||||||
|
if (!store.security.secureCookie) info.secureCookie = false;
|
||||||
|
|
||||||
|
if (Object.keys(info).length === 0) return;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
};
|
||||||
|
|
||||||
|
const gatherDebugInfo = () => {
|
||||||
|
const debugInfo: DebugInfo = {
|
||||||
|
core: coreInfo(),
|
||||||
|
storage: storageInfo(),
|
||||||
|
pruning: pruningInfo(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const security = securityInfo();
|
||||||
|
|
||||||
|
if (security) debugInfo.security = security;
|
||||||
|
|
||||||
|
return debugInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
const toMarkdown = (debugInfo: DebugInfo): string => {
|
||||||
|
let markdown = '# Debug info\n\n';
|
||||||
|
|
||||||
|
for (const sectionKey in debugInfo) {
|
||||||
|
markdown += `## ${sectionKey}\n\n`;
|
||||||
|
|
||||||
|
const section = debugInfo[sectionKey as keyof DebugInfo];
|
||||||
|
|
||||||
|
if (!section) continue;
|
||||||
|
|
||||||
|
for (const itemKey in section) {
|
||||||
|
const itemValue = section[itemKey as keyof typeof section];
|
||||||
|
markdown += `- ${itemKey}: ${itemValue}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
markdown += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return markdown;
|
||||||
|
};
|
||||||
|
|
||||||
|
const appendTimestamp = (markdown: string) => {
|
||||||
|
return `${markdown}Generated at: ${new Date().toISOString()}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const generateDebugInfo = () => {
|
||||||
|
return appendTimestamp(toMarkdown(gatherDebugInfo()));
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
generateDebugInfo,
|
||||||
|
};
|
||||||
|
}
|
|
@ -78,6 +78,10 @@
|
||||||
"about.n8nVersion": "n8n Version",
|
"about.n8nVersion": "n8n Version",
|
||||||
"about.sourceCode": "Source Code",
|
"about.sourceCode": "Source Code",
|
||||||
"about.instanceID": "Instance ID",
|
"about.instanceID": "Instance ID",
|
||||||
|
"about.debug.title": "Debug",
|
||||||
|
"about.debug.message": "Copy debug information",
|
||||||
|
"about.debug.toast.title": "Debug info",
|
||||||
|
"about.debug.toast.message": "Copied debug info to clipboard",
|
||||||
"askAi.dialog.title": "'Ask AI' is almost ready",
|
"askAi.dialog.title": "'Ask AI' is almost ready",
|
||||||
"askAi.dialog.body": "We’re still applying the finishing touches. Soon, you will be able to <strong>automatically generate code from simple text prompts</strong>. Join the waitlist to get early access to this feature.",
|
"askAi.dialog.body": "We’re still applying the finishing touches. Soon, you will be able to <strong>automatically generate code from simple text prompts</strong>. Join the waitlist to get early access to this feature.",
|
||||||
"askAi.dialog.signup": "Join Waitlist",
|
"askAi.dialog.signup": "Join Waitlist",
|
||||||
|
|
|
@ -68,15 +68,50 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, {
|
||||||
saveDataErrorExecution: 'all',
|
saveDataErrorExecution: 'all',
|
||||||
saveDataSuccessExecution: 'all',
|
saveDataSuccessExecution: 'all',
|
||||||
saveManualExecutions: false,
|
saveManualExecutions: false,
|
||||||
|
saveDataProgressExecution: false,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
|
isDocker(): boolean {
|
||||||
|
return this.settings.isDocker;
|
||||||
|
},
|
||||||
|
databaseType(): 'sqlite' | 'mariadb' | 'mysqldb' | 'postgresdb' {
|
||||||
|
return this.settings.databaseType;
|
||||||
|
},
|
||||||
|
planName(): string {
|
||||||
|
return this.settings.license.planName ?? 'Community';
|
||||||
|
},
|
||||||
|
consumerId(): string {
|
||||||
|
return this.settings.license.consumerId;
|
||||||
|
},
|
||||||
|
binaryDataMode(): 'default' | 'filesystem' | 's3' {
|
||||||
|
return this.settings.binaryDataMode;
|
||||||
|
},
|
||||||
|
pruning(): { isEnabled: boolean; maxAge: number; maxCount: number } {
|
||||||
|
return this.settings.pruning;
|
||||||
|
},
|
||||||
|
security(): {
|
||||||
|
blockFileAccessToN8nFiles: boolean;
|
||||||
|
secureCookie: boolean;
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
blockFileAccessToN8nFiles: this.settings.security.blockFileAccessToN8nFiles,
|
||||||
|
secureCookie: this.settings.authCookie.secure,
|
||||||
|
};
|
||||||
|
},
|
||||||
isEnterpriseFeatureEnabled() {
|
isEnterpriseFeatureEnabled() {
|
||||||
return (feature: EnterpriseEditionFeatureValue): boolean =>
|
return (feature: EnterpriseEditionFeatureValue): boolean =>
|
||||||
Boolean(this.settings.enterprise?.[feature]);
|
Boolean(this.settings.enterprise?.[feature]);
|
||||||
},
|
},
|
||||||
|
|
||||||
versionCli(): string {
|
versionCli(): string {
|
||||||
return this.settings.versionCli;
|
return this.settings.versionCli;
|
||||||
},
|
},
|
||||||
|
nodeJsVersion(): string {
|
||||||
|
return this.settings.nodeJsVersion;
|
||||||
|
},
|
||||||
|
concurrency(): number {
|
||||||
|
return this.settings.concurrency;
|
||||||
|
},
|
||||||
isPublicApiEnabled(): boolean {
|
isPublicApiEnabled(): boolean {
|
||||||
return this.api.enabled;
|
return this.api.enabled;
|
||||||
},
|
},
|
||||||
|
@ -269,6 +304,7 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, {
|
||||||
this.setAllowedModules(settings.allowedModules);
|
this.setAllowedModules(settings.allowedModules);
|
||||||
this.setSaveDataErrorExecution(settings.saveDataErrorExecution);
|
this.setSaveDataErrorExecution(settings.saveDataErrorExecution);
|
||||||
this.setSaveDataSuccessExecution(settings.saveDataSuccessExecution);
|
this.setSaveDataSuccessExecution(settings.saveDataSuccessExecution);
|
||||||
|
this.setSaveDataProgressExecution(settings.saveExecutionProgress);
|
||||||
this.setSaveManualExecutions(settings.saveManualExecutions);
|
this.setSaveManualExecutions(settings.saveManualExecutions);
|
||||||
|
|
||||||
rootStore.setUrlBaseWebhook(settings.urlBaseWebhook);
|
rootStore.setUrlBaseWebhook(settings.urlBaseWebhook);
|
||||||
|
@ -357,15 +393,18 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, {
|
||||||
const rootStore = useRootStore();
|
const rootStore = useRootStore();
|
||||||
return await runLdapSync(rootStore.restApiContext, data);
|
return await runLdapSync(rootStore.restApiContext, data);
|
||||||
},
|
},
|
||||||
setSaveDataErrorExecution(newValue: string) {
|
setSaveDataErrorExecution(newValue: WorkflowSettings.SaveDataExecution) {
|
||||||
this.saveDataErrorExecution = newValue;
|
this.saveDataErrorExecution = newValue;
|
||||||
},
|
},
|
||||||
setSaveDataSuccessExecution(newValue: string) {
|
setSaveDataSuccessExecution(newValue: WorkflowSettings.SaveDataExecution) {
|
||||||
this.saveDataSuccessExecution = newValue;
|
this.saveDataSuccessExecution = newValue;
|
||||||
},
|
},
|
||||||
setSaveManualExecutions(saveManualExecutions: boolean) {
|
setSaveManualExecutions(saveManualExecutions: boolean) {
|
||||||
this.saveManualExecutions = saveManualExecutions;
|
this.saveManualExecutions = saveManualExecutions;
|
||||||
},
|
},
|
||||||
|
setSaveDataProgressExecution(newValue: boolean) {
|
||||||
|
this.saveDataProgressExecution = newValue;
|
||||||
|
},
|
||||||
async getTimezones(): Promise<IDataObject> {
|
async getTimezones(): Promise<IDataObject> {
|
||||||
const rootStore = useRootStore();
|
const rootStore = useRootStore();
|
||||||
return await makeRestApiRequest(rootStore.restApiContext, 'GET', '/options/timezones');
|
return await makeRestApiRequest(rootStore.restApiContext, 'GET', '/options/timezones');
|
||||||
|
|
|
@ -2560,6 +2560,8 @@ export type ExpressionEvaluatorType = 'tmpl' | 'tournament';
|
||||||
export type N8nAIProviderType = 'openai' | 'unknown';
|
export type N8nAIProviderType = 'openai' | 'unknown';
|
||||||
|
|
||||||
export interface IN8nUISettings {
|
export interface IN8nUISettings {
|
||||||
|
isDocker: boolean;
|
||||||
|
databaseType: 'sqlite' | 'mariadb' | 'mysqldb' | 'postgresdb';
|
||||||
endpointForm: string;
|
endpointForm: string;
|
||||||
endpointFormTest: string;
|
endpointFormTest: string;
|
||||||
endpointFormWaiting: string;
|
endpointFormWaiting: string;
|
||||||
|
@ -2568,6 +2570,7 @@ export interface IN8nUISettings {
|
||||||
saveDataErrorExecution: WorkflowSettings.SaveDataExecution;
|
saveDataErrorExecution: WorkflowSettings.SaveDataExecution;
|
||||||
saveDataSuccessExecution: WorkflowSettings.SaveDataExecution;
|
saveDataSuccessExecution: WorkflowSettings.SaveDataExecution;
|
||||||
saveManualExecutions: boolean;
|
saveManualExecutions: boolean;
|
||||||
|
saveExecutionProgress: boolean;
|
||||||
executionTimeout: number;
|
executionTimeout: number;
|
||||||
maxExecutionTimeout: number;
|
maxExecutionTimeout: number;
|
||||||
workflowCallerPolicyDefaultOption: WorkflowSettings.CallerPolicy;
|
workflowCallerPolicyDefaultOption: WorkflowSettings.CallerPolicy;
|
||||||
|
@ -2579,10 +2582,12 @@ export interface IN8nUISettings {
|
||||||
urlBaseWebhook: string;
|
urlBaseWebhook: string;
|
||||||
urlBaseEditor: string;
|
urlBaseEditor: string;
|
||||||
versionCli: string;
|
versionCli: string;
|
||||||
|
nodeJsVersion: string;
|
||||||
|
concurrency: number;
|
||||||
authCookie: {
|
authCookie: {
|
||||||
secure: boolean;
|
secure: boolean;
|
||||||
};
|
};
|
||||||
binaryDataMode: string;
|
binaryDataMode: 'default' | 'filesystem' | 's3';
|
||||||
releaseChannel: 'stable' | 'beta' | 'nightly' | 'dev';
|
releaseChannel: 'stable' | 'beta' | 'nightly' | 'dev';
|
||||||
n8nMetadata?: {
|
n8nMetadata?: {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
|
@ -2658,6 +2663,8 @@ export interface IN8nUISettings {
|
||||||
};
|
};
|
||||||
hideUsagePage: boolean;
|
hideUsagePage: boolean;
|
||||||
license: {
|
license: {
|
||||||
|
planName?: string;
|
||||||
|
consumerId: string;
|
||||||
environment: 'development' | 'production' | 'staging';
|
environment: 'development' | 'production' | 'staging';
|
||||||
};
|
};
|
||||||
variables: {
|
variables: {
|
||||||
|
@ -2683,6 +2690,14 @@ export interface IN8nUISettings {
|
||||||
pruneTime: number;
|
pruneTime: number;
|
||||||
licensePruneTime: number;
|
licensePruneTime: number;
|
||||||
};
|
};
|
||||||
|
pruning: {
|
||||||
|
isEnabled: boolean;
|
||||||
|
maxAge: number;
|
||||||
|
maxCount: number;
|
||||||
|
};
|
||||||
|
security: {
|
||||||
|
blockFileAccessToN8nFiles: boolean;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SecretsHelpersBase {
|
export interface SecretsHelpersBase {
|
||||||
|
|
Loading…
Reference in a new issue