diff --git a/packages/cli/src/License.ts b/packages/cli/src/License.ts index c00e1b1835..9a4597f92a 100644 --- a/packages/cli/src/License.ts +++ b/packages/cli/src/License.ts @@ -132,6 +132,10 @@ export class License { return this.isFeatureEnabled(LICENSE_FEATURES.VERSION_CONTROL); } + isAPIDisabled() { + return this.isFeatureEnabled(LICENSE_FEATURES.API_DISABLED); + } + getCurrentEntitlements() { return this.manager?.getCurrentEntitlements() ?? []; } diff --git a/packages/cli/src/PublicApi/index.ts b/packages/cli/src/PublicApi/index.ts index fa27212db4..4ffa4d7fe5 100644 --- a/packages/cli/src/PublicApi/index.ts +++ b/packages/cli/src/PublicApi/index.ts @@ -16,6 +16,7 @@ import * as Db from '@/Db'; import { getInstanceBaseUrl } from '@/UserManagement/UserManagementHelper'; import { Container } from 'typedi'; import { InternalHooks } from '@/InternalHooks'; +import { License } from '@/License'; async function createApiRouter( version: string, @@ -151,3 +152,12 @@ export const loadPublicApiVersions = async ( apiLatestVersion: Number(versions.pop()?.charAt(1)) ?? 1, }; }; + +function isApiEnabledByLicense(): boolean { + const license = Container.get(License); + return !license.isAPIDisabled(); +} + +export function isApiEnabled(): boolean { + return !config.get('publicApi.disabled') && isApiEnabledByLicense(); +} diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index f5406d2b2d..8739fe9ed1 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -97,7 +97,7 @@ import { import { executionsController } from '@/executions/executions.controller'; import { workflowStatsController } from '@/api/workflowStats.api'; -import { loadPublicApiVersions } from '@/PublicApi'; +import { isApiEnabled, loadPublicApiVersions } from '@/PublicApi'; import { getInstanceBaseUrl, isEmailSetUp, @@ -277,7 +277,7 @@ export class Server extends AbstractServer { }, }, publicApi: { - enabled: !config.getEnv('publicApi.disabled'), + enabled: isApiEnabled(), latestVersion: 1, path: config.getEnv('publicApi.path'), swaggerUi: { @@ -538,7 +538,7 @@ export class Server extends AbstractServer { this.endpointWebhook, this.endpointWebhookTest, this.endpointPresetCredentials, - config.getEnv('publicApi.disabled') ? publicApiEndpoint : '', + isApiEnabled() ? '' : publicApiEndpoint, ...excludeEndpoints.split(':'), ].filter((u) => !!u); @@ -564,7 +564,7 @@ export class Server extends AbstractServer { // Public API // ---------------------------------------- - if (!config.getEnv('publicApi.disabled')) { + if (isApiEnabled()) { const { apiRouters, apiLatestVersion } = await loadPublicApiVersions(publicApiEndpoint); this.app.use(...apiRouters); this.frontendSettings.publicApi.latestVersion = apiLatestVersion; diff --git a/packages/cli/src/audit/risks/instance.risk.ts b/packages/cli/src/audit/risks/instance.risk.ts index 0bd0c18fb3..6d75acbd98 100644 --- a/packages/cli/src/audit/risks/instance.risk.ts +++ b/packages/cli/src/audit/risks/instance.risk.ts @@ -13,6 +13,7 @@ import { import { getN8nPackageJson, inDevelopment } from '@/constants'; import type { WorkflowEntity } from '@db/entities/WorkflowEntity'; import type { Risk, n8n } from '@/audit/types'; +import { isApiEnabled } from '@/PublicApi'; function getSecuritySettings() { if (config.getEnv('deployment.type') === 'cloud') return null; @@ -34,7 +35,7 @@ function getSecuritySettings() { communityPackagesEnabled: config.getEnv('nodes.communityPackages.enabled'), versionNotificationsEnabled: config.getEnv('versionNotifications.enabled'), templatesEnabled: config.getEnv('templates.enabled'), - publicApiEnabled: !config.getEnv('publicApi.disabled'), + publicApiEnabled: isApiEnabled(), userManagementEnabled, }; diff --git a/packages/cli/src/constants.ts b/packages/cli/src/constants.ts index 818364bc5c..049f103cc9 100644 --- a/packages/cli/src/constants.ts +++ b/packages/cli/src/constants.ts @@ -78,6 +78,7 @@ export const enum LICENSE_FEATURES { ADVANCED_EXECUTION_FILTERS = 'feat:advancedExecutionFilters', VARIABLES = 'feat:variables', VERSION_CONTROL = 'feat:versionControl', + API_DISABLED = 'feat:apiDisabled', } export const enum LICENSE_QUOTAS { diff --git a/packages/design-system/src/components/N8nButton/Button.vue b/packages/design-system/src/components/N8nButton/Button.vue index 127a1abd5f..ad899a10c6 100644 --- a/packages/design-system/src/components/N8nButton/Button.vue +++ b/packages/design-system/src/components/N8nButton/Button.vue @@ -38,7 +38,7 @@ export default defineComponent({ type: String, default: 'medium', validator: (value: string): boolean => - ['mini', 'small', 'medium', 'large', 'xlarge'].includes(value), + ['xmini', 'mini', 'small', 'medium', 'large', 'xlarge'].includes(value), }, loading: { type: Boolean, @@ -278,6 +278,17 @@ $loading-overlay-background-color: rgba(255, 255, 255, 0); * Sizes */ +.xmini { + --button-padding-vertical: var(--spacing-4xs); + --button-padding-horizontal: var(--spacing-3xs); + --button-font-size: var(--font-size-3xs); + + &.square { + height: 22px; + width: 22px; + } +} + .mini { --button-padding-vertical: var(--spacing-4xs); --button-padding-horizontal: var(--spacing-2xs); diff --git a/packages/design-system/src/components/N8nMenu/Menu.vue b/packages/design-system/src/components/N8nMenu/Menu.vue index 66e9d61bb4..6dafe805fc 100644 --- a/packages/design-system/src/components/N8nMenu/Menu.vue +++ b/packages/design-system/src/components/N8nMenu/Menu.vue @@ -28,6 +28,7 @@