mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-19 07:26:02 +02:00
97 lines
3.3 KiB
TypeScript
97 lines
3.3 KiB
TypeScript
import { UpdateSecuritySettingsDto } from '@n8n/api-types';
|
|
import { LicenseState } from '@n8n/backend-common';
|
|
import { InstanceSettingsLoaderConfig } from '@n8n/config';
|
|
import { type AuthenticatedRequest } from '@n8n/db';
|
|
import { Body, Get, GlobalScope, Licensed, Post, RestController } from '@n8n/decorators';
|
|
import type { Response } from 'express';
|
|
|
|
import { ForbiddenError } from '@n8n/errors';
|
|
import { SecuritySettingsService } from '@/services/security-settings.service';
|
|
import { WorkflowReviewPolicyService } from '@/services/workflow-review-policy.service';
|
|
|
|
@RestController('/settings/security')
|
|
export class SecuritySettingsController {
|
|
constructor(
|
|
private readonly securitySettingsService: SecuritySettingsService,
|
|
private readonly workflowReviewPolicyService: WorkflowReviewPolicyService,
|
|
private readonly licenseState: LicenseState,
|
|
private readonly instanceSettingsLoaderConfig: InstanceSettingsLoaderConfig,
|
|
) {}
|
|
|
|
@Licensed('feat:personalSpacePolicy')
|
|
@GlobalScope('securitySettings:manage')
|
|
@Get('/')
|
|
async getSecuritySettings(_req: AuthenticatedRequest, _res: Response) {
|
|
const [settings, workflowReviews] = await Promise.all([
|
|
this.securitySettingsService.getSecuritySettings(),
|
|
this.getWorkflowReviewsIfAvailable(),
|
|
]);
|
|
|
|
return {
|
|
...settings,
|
|
managedByEnv: this.instanceSettingsLoaderConfig.securityPolicyManagedByEnv,
|
|
...(workflowReviews !== undefined ? { workflowReviews } : {}),
|
|
};
|
|
}
|
|
|
|
@Licensed('feat:personalSpacePolicy')
|
|
@GlobalScope('securitySettings:manage')
|
|
@Post('/')
|
|
async updateSecuritySettings(
|
|
req: AuthenticatedRequest,
|
|
_res: Response,
|
|
@Body dto: UpdateSecuritySettingsDto,
|
|
) {
|
|
if (this.instanceSettingsLoaderConfig.securityPolicyManagedByEnv) {
|
|
throw new ForbiddenError(
|
|
'Security settings are managed via environment variables and cannot be modified through the API',
|
|
);
|
|
}
|
|
|
|
if (dto.workflowReviews !== undefined) {
|
|
this.assertWorkflowReviewsAvailable();
|
|
}
|
|
|
|
const updatedSettings: Partial<UpdateSecuritySettingsDto> =
|
|
await this.securitySettingsService.updateSecuritySettings(
|
|
{
|
|
personalSpacePublishing: dto.personalSpacePublishing,
|
|
personalSpaceSharing: dto.personalSpaceSharing,
|
|
redactionEnforcement: dto.redactionEnforcement,
|
|
},
|
|
req.user,
|
|
);
|
|
|
|
if (dto.workflowReviews?.enabled !== undefined) {
|
|
const before = (await this.workflowReviewPolicyService.get()).enabled;
|
|
const after = dto.workflowReviews.enabled;
|
|
updatedSettings.workflowReviews = { enabled: after };
|
|
if (before !== after) {
|
|
const workflowReviews = await this.workflowReviewPolicyService.set(after);
|
|
updatedSettings.workflowReviews = workflowReviews;
|
|
this.securitySettingsService.emitInstancePolicyUpdated(req.user, {
|
|
settingName: 'workflow_reviews',
|
|
value: workflowReviews.enabled,
|
|
});
|
|
}
|
|
}
|
|
|
|
return updatedSettings;
|
|
}
|
|
|
|
private isWorkflowReviewsAvailable(): boolean {
|
|
return this.licenseState.isWorkflowReviewsLicensed();
|
|
}
|
|
|
|
private async getWorkflowReviewsIfAvailable() {
|
|
if (!this.isWorkflowReviewsAvailable()) return undefined;
|
|
return await this.workflowReviewPolicyService.get();
|
|
}
|
|
|
|
private assertWorkflowReviewsAvailable(): void {
|
|
if (!this.isWorkflowReviewsAvailable()) {
|
|
throw new ForbiddenError('Workflow reviews settings are not enabled in this instance');
|
|
}
|
|
}
|
|
}
|