diff --git a/server/.env.example b/server/.env.example index 5edf5a936a..db468d7ef5 100644 --- a/server/.env.example +++ b/server/.env.example @@ -24,4 +24,5 @@ SIGN_IN_PREFILLED=true # SUPPORT_FRONT_CHAT_ID=replace_me_with_front_chat_id # LOGGER_DRIVER=console # SENTRY_DSN=https://xxx@xxx.ingest.sentry.io/xxx -# LOG_LEVEL=error,warn \ No newline at end of file +# LOG_LEVEL=error,warn +# FLEXIBLE_BACKEND_ENABLED=false \ No newline at end of file diff --git a/server/src/core/client-config/client-config.entity.ts b/server/src/core/client-config/client-config.entity.ts index 079a76008e..c26035d7d6 100644 --- a/server/src/core/client-config/client-config.entity.ts +++ b/server/src/core/client-config/client-config.entity.ts @@ -44,6 +44,9 @@ export class ClientConfig { @Field(() => Boolean) debugMode: boolean; + @Field(() => Boolean) + flexibleBackendEnabled: boolean; + @Field(() => Support) support: Support; } diff --git a/server/src/core/client-config/client-config.resolver.ts b/server/src/core/client-config/client-config.resolver.ts index 1f4d753ba1..736bfbfae2 100644 --- a/server/src/core/client-config/client-config.resolver.ts +++ b/server/src/core/client-config/client-config.resolver.ts @@ -23,6 +23,8 @@ export class ClientConfigResolver { }, signInPrefilled: this.environmentService.isSignInPrefilled(), debugMode: this.environmentService.isDebugMode(), + flexibleBackendEnabled: + this.environmentService.isFlexibleBackendEnabled(), support: { supportDriver: this.environmentService.getSupportDriver(), supportFrontChatId: this.environmentService.getSupportFrontChatId(), diff --git a/server/src/integrations/environment/environment.service.ts b/server/src/integrations/environment/environment.service.ts index 90ea8042a3..d57606f33f 100644 --- a/server/src/integrations/environment/environment.service.ts +++ b/server/src/integrations/environment/environment.service.ts @@ -29,6 +29,10 @@ export class EnvironmentService { ); } + isFlexibleBackendEnabled(): boolean { + return this.configService.get('FLEXIBLE_BACKEND_ENABLED') ?? false; + } + getPort(): number { return this.configService.get('PORT') ?? 3000; } diff --git a/server/src/integrations/environment/environment.validation.ts b/server/src/integrations/environment/environment.validation.ts index fe8b4c3edf..956dbad26e 100644 --- a/server/src/integrations/environment/environment.validation.ts +++ b/server/src/integrations/environment/environment.validation.ts @@ -46,6 +46,11 @@ export class EnvironmentVariables { @IsBoolean() TELEMETRY_ANONYMIZATION_ENABLED?: boolean; + @CastToBoolean() + @IsOptional() + @IsBoolean() + FLEXIBLE_BACKEND_ENABLED?: boolean; + @CastToPositiveNumber() @IsNumber() @IsOptional() diff --git a/server/src/tenant/universal/universal.resolver.ts b/server/src/tenant/universal/universal.resolver.ts index bb523b8755..d511f8b1a5 100644 --- a/server/src/tenant/universal/universal.resolver.ts +++ b/server/src/tenant/universal/universal.resolver.ts @@ -1,10 +1,11 @@ import { Args, Query, Resolver } from '@nestjs/graphql'; -import { UseGuards } from '@nestjs/common'; +import { ForbiddenException, UseGuards } from '@nestjs/common'; import { Workspace } from '@prisma/client'; import { JwtAuthGuard } from 'src/guards/jwt.auth.guard'; import { AuthWorkspace } from 'src/decorators/auth-workspace.decorator'; +import { EnvironmentService } from 'src/integrations/environment/environment.service'; import { UniversalEntity, PaginatedUniversalEntity } from './universal.entity'; import { UniversalService } from './universal.service'; @@ -16,13 +17,20 @@ import { UpdateOneCustomArgs } from './args/update-one-custom.args'; @UseGuards(JwtAuthGuard) @Resolver(() => UniversalEntity) export class UniversalResolver { - constructor(private readonly customService: UniversalService) {} + constructor( + private readonly customService: UniversalService, + private readonly environmentService: EnvironmentService, + ) {} @Query(() => PaginatedUniversalEntity) findMany( @Args() args: FindManyUniversalArgs, @AuthWorkspace() workspace: Workspace, ): Promise { + if (!this.environmentService.isFlexibleBackendEnabled()) { + throw new ForbiddenException(); + } + return this.customService.findManyUniversal(args, workspace); } @@ -31,11 +39,19 @@ export class UniversalResolver { @Args() args: FindUniqueUniversalArgs, @AuthWorkspace() workspace: Workspace, ): Promise { + if (!this.environmentService.isFlexibleBackendEnabled()) { + throw new ForbiddenException(); + } + return this.customService.findUniqueUniversal(args, workspace); } @Query(() => UniversalEntity) updateOneCustom(@Args() args: UpdateOneCustomArgs): UniversalEntity { + if (!this.environmentService.isFlexibleBackendEnabled()) { + throw new ForbiddenException(); + } + return { id: 'exampleId', data: {}, @@ -46,6 +62,10 @@ export class UniversalResolver { @Query(() => UniversalEntity) deleteOneCustom(@Args() args: UpdateOneCustomArgs): UniversalEntity { + if (!this.environmentService.isFlexibleBackendEnabled()) { + throw new ForbiddenException(); + } + return { id: 'exampleId', data: {}, diff --git a/server/src/tenant/universal/universal.service.spec.ts b/server/src/tenant/universal/universal.service.spec.ts index 5cc21c13b6..2ab5113f5d 100644 --- a/server/src/tenant/universal/universal.service.spec.ts +++ b/server/src/tenant/universal/universal.service.spec.ts @@ -1,6 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { DataSourceService } from 'src/tenant/metadata/data-source/data-source.service'; +import { EnvironmentService } from 'src/integrations/environment/environment.service'; import { UniversalService } from './universal.service'; @@ -15,6 +16,10 @@ describe('UniversalService', () => { provide: DataSourceService, useValue: {}, }, + { + provide: EnvironmentService, + useValue: {}, + }, ], }).compile();