Prevent file upload in demo workspaces (#4503)
* Build demo env guard * Put guard for auth * Add todo --------- Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
36
packages/twenty-server/src/engine/guards/demo.env.guard.ts
Normal file
36
packages/twenty-server/src/engine/guards/demo.env.guard.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import {
|
||||
Injectable,
|
||||
ExecutionContext,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
import { getRequest } from 'src/utils/extract-request';
|
||||
|
||||
@Injectable()
|
||||
export class DemoEnvGuard extends AuthGuard(['jwt']) {
|
||||
constructor(private readonly environmentService: EnvironmentService) {
|
||||
super();
|
||||
}
|
||||
|
||||
getRequest(context: ExecutionContext) {
|
||||
return getRequest(context);
|
||||
}
|
||||
|
||||
// TODO: input should be typed
|
||||
handleRequest(err: any, user: any) {
|
||||
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||
const currentUserWorkspaceId = user?.workspace?.id;
|
||||
|
||||
if (!currentUserWorkspaceId) {
|
||||
throw new UnauthorizedException('Unauthorized for not logged in user');
|
||||
}
|
||||
|
||||
if (demoWorkspaceIds.includes(currentUserWorkspaceId)) {
|
||||
throw new UnauthorizedException('Unauthorized for demo workspace');
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ import { GoogleAPIsRequest } from 'src/engine/modules/auth/strategies/google-api
|
||||
import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service';
|
||||
import { TokenService } from 'src/engine/modules/auth/services/token.service';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard';
|
||||
|
||||
@Controller('auth/google-apis')
|
||||
export class GoogleAPIsAuthController {
|
||||
@ -25,7 +26,7 @@ export class GoogleAPIsAuthController {
|
||||
}
|
||||
|
||||
@Get('get-access-token')
|
||||
@UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard)
|
||||
@UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard, DemoEnvGuard)
|
||||
async googleAuthGetAccessToken(
|
||||
@Req() req: GoogleAPIsRequest,
|
||||
@Res() res: Response,
|
||||
@ -37,12 +38,6 @@ export class GoogleAPIsAuthController {
|
||||
const { workspaceMemberId, workspaceId } =
|
||||
await this.tokenService.verifyTransientToken(transientToken);
|
||||
|
||||
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||
|
||||
if (demoWorkspaceIds.includes(workspaceId)) {
|
||||
throw new Error('Cannot connect Google account to demo workspace');
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
throw new Error('Workspace not found');
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common';
|
||||
|
||||
import { Response } from 'express';
|
||||
|
||||
import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard';
|
||||
import { GoogleAPIsOauthGuard } from 'src/engine/modules/auth/guards/google-apis-oauth.guard';
|
||||
import { GoogleAPIsProviderEnabledGuard } from 'src/engine/modules/auth/guards/google-apis-provider-enabled.guard';
|
||||
import { GoogleAPIsService } from 'src/engine/modules/auth/services/google-apis.service';
|
||||
@ -25,7 +26,7 @@ export class GoogleGmailAuthController {
|
||||
}
|
||||
|
||||
@Get('get-access-token')
|
||||
@UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard)
|
||||
@UseGuards(GoogleAPIsProviderEnabledGuard, GoogleAPIsOauthGuard, DemoEnvGuard)
|
||||
async googleAuthGetAccessToken(
|
||||
@Req() req: GoogleAPIsRequest,
|
||||
@Res() res: Response,
|
||||
@ -37,25 +38,18 @@ export class GoogleGmailAuthController {
|
||||
const { workspaceMemberId, workspaceId } =
|
||||
await this.tokenService.verifyTransientToken(transientToken);
|
||||
|
||||
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||
|
||||
if (demoWorkspaceIds.includes(workspaceId)) {
|
||||
throw new Error('Cannot connect Gmail account to demo workspace');
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
throw new Error('Workspace not found');
|
||||
}
|
||||
|
||||
if (workspaceId)
|
||||
await this.googleGmailService.saveConnectedAccount({
|
||||
handle: email,
|
||||
workspaceMemberId: workspaceMemberId,
|
||||
workspaceId: workspaceId,
|
||||
provider: 'gmail',
|
||||
accessToken,
|
||||
refreshToken,
|
||||
});
|
||||
await this.googleGmailService.saveConnectedAccount({
|
||||
handle: email,
|
||||
workspaceMemberId: workspaceMemberId,
|
||||
workspaceId: workspaceId,
|
||||
provider: 'gmail',
|
||||
accessToken,
|
||||
refreshToken,
|
||||
});
|
||||
|
||||
return res.redirect(
|
||||
`${this.environmentService.get('FRONT_BASE_URL')}/settings/accounts`,
|
||||
|
||||
@ -1,12 +1,19 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||
|
||||
import { FileService } from './services/file.service';
|
||||
import { FileUploadService } from './services/file-upload.service';
|
||||
import { FileUploadResolver } from './resolvers/file-upload.resolver';
|
||||
import { FileController } from './controllers/file.controller';
|
||||
|
||||
@Module({
|
||||
providers: [FileService, FileUploadService, FileUploadResolver],
|
||||
providers: [
|
||||
FileService,
|
||||
FileUploadService,
|
||||
FileUploadResolver,
|
||||
EnvironmentService,
|
||||
],
|
||||
exports: [FileService, FileUploadService],
|
||||
controllers: [FileController],
|
||||
})
|
||||
|
||||
@ -8,8 +8,9 @@ import { FileFolder } from 'src/engine/modules/file/interfaces/file-folder.inter
|
||||
import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service';
|
||||
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||
import { streamToBuffer } from 'src/utils/stream-to-buffer';
|
||||
import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UseGuards(JwtAuthGuard, DemoEnvGuard)
|
||||
@Resolver()
|
||||
export class FileUploadResolver {
|
||||
constructor(private readonly fileUploadService: FileUploadService) {}
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
ResolveField,
|
||||
Mutation,
|
||||
} from '@nestjs/graphql';
|
||||
import { ForbiddenException, UseGuards } from '@nestjs/common';
|
||||
import { UseGuards } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import crypto from 'crypto';
|
||||
@ -22,6 +22,7 @@ import { EnvironmentService } from 'src/engine/integrations/environment/environm
|
||||
import { streamToBuffer } from 'src/utils/stream-to-buffer';
|
||||
import { FileUploadService } from 'src/engine/modules/file/services/file-upload.service';
|
||||
import { assert } from 'src/utils/assert';
|
||||
import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard';
|
||||
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||
import { User } from 'src/engine/modules/user/user.entity';
|
||||
import { WorkspaceMember } from 'src/engine/modules/user/dtos/workspace-member.dto';
|
||||
@ -108,20 +109,9 @@ export class UserResolver {
|
||||
return paths[0];
|
||||
}
|
||||
|
||||
@UseGuards(DemoEnvGuard)
|
||||
@Mutation(() => User)
|
||||
async deleteUser(@AuthUser() { id: userId, defaultWorkspace }: User) {
|
||||
// Get the list of demo workspace IDs
|
||||
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||
|
||||
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.',
|
||||
);
|
||||
}
|
||||
|
||||
async deleteUser(@AuthUser() { id: userId }: User) {
|
||||
// Proceed with user deletion
|
||||
return this.userService.deleteUser(userId);
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
ResolveField,
|
||||
Parent,
|
||||
} from '@nestjs/graphql';
|
||||
import { ForbiddenException, UseGuards } from '@nestjs/common';
|
||||
import { UseGuards } from '@nestjs/common';
|
||||
|
||||
import { FileUpload, GraphQLUpload } from 'graphql-upload';
|
||||
|
||||
@ -18,12 +18,12 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat
|
||||
import { assert } from 'src/utils/assert';
|
||||
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||
import { UpdateWorkspaceInput } from 'src/engine/modules/workspace/dtos/update-workspace-input';
|
||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||
import { User } from 'src/engine/modules/user/user.entity';
|
||||
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
||||
import { ActivateWorkspaceInput } from 'src/engine/modules/workspace/dtos/activate-workspace-input';
|
||||
import { BillingSubscription } from 'src/engine/modules/billing/entities/billing-subscription.entity';
|
||||
import { BillingService } from 'src/engine/modules/billing/billing.service';
|
||||
import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard';
|
||||
|
||||
import { Workspace } from './workspace.entity';
|
||||
|
||||
@ -35,7 +35,6 @@ export class WorkspaceResolver {
|
||||
constructor(
|
||||
private readonly workspaceService: WorkspaceService,
|
||||
private readonly fileUploadService: FileUploadService,
|
||||
private readonly environmentService: EnvironmentService,
|
||||
private readonly billingService: BillingService,
|
||||
) {}
|
||||
|
||||
@ -89,15 +88,9 @@ export class WorkspaceResolver {
|
||||
return paths[0];
|
||||
}
|
||||
|
||||
@UseGuards(DemoEnvGuard)
|
||||
@Mutation(() => Workspace)
|
||||
async deleteCurrentWorkspace(@AuthWorkspace() { id }: Workspace) {
|
||||
const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user