From 351dc6488c35fb605f9aded394d9d398216ec7bb Mon Sep 17 00:00:00 2001 From: Ruslan <396223+khakimov@users.noreply.github.com> Date: Wed, 20 Dec 2023 20:52:44 +0700 Subject: [PATCH] feat(workspace-resolver): prevent deletion of demo workspaces (#2207) (#3068) * feat(workspace-resolver): prevent deletion of demo workspaces (#2207) * ForbiddenException instead of Error * Optimize user and workspace deletion checks and clarify exception messages (#2207) - ForbiddenException messages for attempts to delete users and workspaces associated with demo accounts --- .../src/core/user/user.resolver.ts | 17 +++++++++++++++-- .../src/core/workspace/workspace.resolver.ts | 11 ++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/twenty-server/src/core/user/user.resolver.ts b/packages/twenty-server/src/core/user/user.resolver.ts index b4a0e2268..5be793e14 100644 --- a/packages/twenty-server/src/core/user/user.resolver.ts +++ b/packages/twenty-server/src/core/user/user.resolver.ts @@ -6,7 +6,7 @@ import { ResolveField, Mutation, } from '@nestjs/graphql'; -import { UseGuards } from '@nestjs/common'; +import { ForbiddenException, UseGuards } from '@nestjs/common'; import crypto from 'crypto'; @@ -98,7 +98,20 @@ export class UserResolver { } @Mutation(() => User) - async deleteUser(@AuthUser() { id: userId }: User) { + async deleteUser(@AuthUser() { id: userId, defaultWorkspace }: User) { + // Get the list of demo workspace IDs + const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds(); + + const currentUserWorkspaceId = defaultWorkspace.id; + + // Check if the user's default workspace ID is in the list of demo workspace IDs + if (demoWorkspaceIds.includes(currentUserWorkspaceId)) { + throw new ForbiddenException( + 'Deletion of users with a default demo workspace is not allowed.', + ); + } + + // Proceed with user deletion return this.userService.deleteUser(userId); } } diff --git a/packages/twenty-server/src/core/workspace/workspace.resolver.ts b/packages/twenty-server/src/core/workspace/workspace.resolver.ts index 13c5fc92c..e588fad93 100644 --- a/packages/twenty-server/src/core/workspace/workspace.resolver.ts +++ b/packages/twenty-server/src/core/workspace/workspace.resolver.ts @@ -1,5 +1,5 @@ import { Resolver, Query, Args, Mutation } from '@nestjs/graphql'; -import { UseGuards } from '@nestjs/common'; +import { ForbiddenException, UseGuards } from '@nestjs/common'; import { FileUpload, GraphQLUpload } from 'graphql-upload'; @@ -11,6 +11,7 @@ import { AuthWorkspace } from 'src/decorators/auth-workspace.decorator'; import { assert } from 'src/utils/assert'; import { JwtAuthGuard } from 'src/guards/jwt.auth.guard'; import { UpdateWorkspaceInput } from 'src/core/workspace/dtos/update-workspace-input'; +import { EnvironmentService } from 'src/integrations/environment/environment.service'; import { Workspace } from './workspace.entity'; @@ -22,6 +23,7 @@ export class WorkspaceResolver { constructor( private readonly workspaceService: WorkspaceService, private readonly fileUploadService: FileUploadService, + private readonly environmentService: EnvironmentService, ) {} @Query(() => Workspace) @@ -67,6 +69,13 @@ export class WorkspaceResolver { @Mutation(() => Workspace) async deleteCurrentWorkspace(@AuthWorkspace() { id }: Workspace) { + const demoWorkspaceIds = this.environmentService.getDemoWorkspaceIds(); + + // Check if the id is in the list of demo workspaceIds + if (demoWorkspaceIds.includes(id)) { + throw new ForbiddenException('Demo workspaces cannot be deleted.'); + } + return this.workspaceService.deleteWorkspace(id); } }