Skip to content

Commit cfca041

Browse files
authored
chore(editor): Gate personal space policy settings behind license feature (#25527)
1 parent 8801764 commit cfca041

15 files changed

Lines changed: 164 additions & 19 deletions

File tree

packages/@n8n/api-types/src/frontend-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export interface IEnterpriseSettings {
6060
};
6161
};
6262
customRoles: boolean;
63+
personalSpacePolicy: boolean;
6364
}
6465

6566
export interface FrontendSettings {

packages/@n8n/backend-common/src/license-state.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export class LicenseState {
6262
return this.isLicensed(LICENSE_FEATURES.DYNAMIC_CREDENTIALS);
6363
}
6464

65+
isPersonalSpacePolicyLicensed() {
66+
return this.isLicensed(LICENSE_FEATURES.PERSONAL_SPACE_POLICY);
67+
}
68+
6569
isSharingLicensed() {
6670
return this.isLicensed('feat:sharing');
6771
}

packages/@n8n/constants/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export const LICENSE_FEATURES = {
4040
CUSTOM_ROLES: 'feat:customRoles',
4141
AI_BUILDER: 'feat:aiBuilder',
4242
DYNAMIC_CREDENTIALS: 'feat:dynamicCredentials',
43+
PERSONAL_SPACE_POLICY: 'feat:personalSpacePolicy',
4344
} as const;
4445

4546
export const LICENSE_QUOTAS = {

packages/cli/src/controllers/e2e.controller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export class E2EController {
122122
[LICENSE_FEATURES.NAMED_VERSIONS]: false,
123123
[LICENSE_FEATURES.CUSTOM_ROLES]: false,
124124
[LICENSE_FEATURES.AI_BUILDER]: false,
125+
[LICENSE_FEATURES.PERSONAL_SPACE_POLICY]: false,
125126
};
126127

127128
private static readonly numericFeaturesDefaults: Record<NumericLicenseFeature, number> = {

packages/cli/src/controllers/security-settings.controller.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { UpdateSecuritySettingsDto } from '@n8n/api-types';
22
import { type AuthenticatedRequest } from '@n8n/db';
3-
import { Body, Get, GlobalScope, Post, RestController } from '@n8n/decorators';
3+
import { Body, Get, GlobalScope, Licensed, Post, RestController } from '@n8n/decorators';
44
import {
55
PERSONAL_SPACE_PUBLISHING_SETTING,
66
PERSONAL_SPACE_SHARING_SETTING,
@@ -17,6 +17,7 @@ export class SecuritySettingsController {
1717
private readonly eventService: EventService,
1818
) {}
1919

20+
@Licensed('feat:personalSpacePolicy')
2021
@GlobalScope('securitySettings:manage')
2122
@Get('/')
2223
async getSecuritySettings(_req: AuthenticatedRequest, _res: Response) {
@@ -39,6 +40,7 @@ export class SecuritySettingsController {
3940
};
4041
}
4142

43+
@Licensed('feat:personalSpacePolicy')
4244
@GlobalScope('securitySettings:manage')
4345
@Post('/')
4446
async updateSecuritySettings(

packages/cli/src/services/frontend.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ export class FrontendService {
318318
},
319319
},
320320
customRoles: false,
321+
personalSpacePolicy: false,
321322
},
322323
mfa: {
323324
enabled: false,
@@ -460,6 +461,7 @@ export class FrontendService {
460461
workflowDiffs: this.licenseState.isWorkflowDiffsLicensed(),
461462
namedVersions: this.license.isLicensed(LICENSE_FEATURES.NAMED_VERSIONS),
462463
customRoles: this.licenseState.isCustomRolesLicensed(),
464+
personalSpacePolicy: this.licenseState.isPersonalSpacePolicyLicensed(),
463465
});
464466

465467
if (this.license.isLdapEnabled()) {

packages/cli/test/integration/controllers/security-settings.controller.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,15 @@ describe('SecuritySettingsController', () => {
2323

2424
beforeEach(() => {
2525
jest.clearAllMocks();
26+
testServer.license.enable('feat:personalSpacePolicy');
2627
});
2728

2829
describe('GET /settings/security', () => {
30+
it('should return 403 when personalSpacePolicy license is not active', async () => {
31+
testServer.license.disable('feat:personalSpacePolicy');
32+
await ownerAgent.get('/settings/security').expect(403);
33+
});
34+
2935
it('should return security settings and all counts', async () => {
3036
securitySettingsService.arePersonalSpaceSettingsEnabled.mockResolvedValue({
3137
personalSpacePublishing: true,
@@ -78,6 +84,14 @@ describe('SecuritySettingsController', () => {
7884
});
7985

8086
describe('POST /settings/security', () => {
87+
it('should return 403 when personalSpacePolicy license is not active', async () => {
88+
testServer.license.disable('feat:personalSpacePolicy');
89+
await ownerAgent
90+
.post('/settings/security')
91+
.send({ personalSpacePublishing: true })
92+
.expect(403);
93+
});
94+
8195
it('should update only personalSpacePublishing when only that is set in body', async () => {
8296
securitySettingsService.setPersonalSpaceSetting.mockResolvedValue(undefined);
8397

packages/frontend/@n8n/i18n/src/locales/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3995,6 +3995,8 @@
39953995
"settings.security.personalSpace.sharing.confirmMessage.disable.message": "This will prevent sharing workflows and credentials from personal spaces going forwards. Existing shares will remain in place.",
39963996
"settings.security.personalSpace.sharing.existingCount.label": "Existing shares",
39973997
"settings.security.personalSpace.sharing.existingCount.value": "{workflowCount} workflows, {credentialCount} credentials",
3998+
"settings.security.personalSpace.unlicensed_tooltip": "Upgrade to a plan that includes personal space policies to manage this setting. {action}",
3999+
"settings.security.personalSpace.unlicensed_tooltip.link": "Upgrade now",
39984000
"settings.sso": "SSO",
39994001
"settings.sso.title": "Single Sign On",
40004002
"settings.sso.subtitle": "SAML 2.0 Configuration",

packages/frontend/editor-ui/src/Interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,7 @@ export type EnterpriseEditionFeatureKey =
949949
| 'EnforceMFA'
950950
| 'NamedVersions'
951951
| 'Provisioning'
952+
| 'PersonalSpacePolicy'
952953
| 'CustomRoles';
953954

954955
export type EnterpriseEditionFeatureValue = keyof Omit<FrontendSettings['enterprise'], 'projects'>;

packages/frontend/editor-ui/src/__tests__/defaults.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const defaultSettings: FrontendSettings = {
5151
},
5252
},
5353
customRoles: false,
54+
personalSpacePolicy: false,
5455
},
5556
executionMode: 'regular',
5657
isMultiMain: false,

0 commit comments

Comments
 (0)