diff --git a/packages/twenty-server/src/app.module.ts b/packages/twenty-server/src/app.module.ts index c7af6a6450..b076874c72 100644 --- a/packages/twenty-server/src/app.module.ts +++ b/packages/twenty-server/src/app.module.ts @@ -21,8 +21,8 @@ import { MetadataGraphQLApiModule } from 'src/engine/api/graphql/metadata-graphq import { GraphQLConfigModule } from 'src/engine/api/graphql/graphql-config/graphql-config.module'; import { GraphQLConfigService } from 'src/engine/api/graphql/graphql-config/graphql-config.service'; import { EnvironmentService } from 'src/engine/integrations/environment/environment.service'; -import { UserWorkspaceMiddleware } from 'src/engine/middlewares/user-workspace.middleware'; import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; +import { GraphQLHydrateRequestFromTokenMiddleware } from 'src/engine/middlewares/graphql-hydrate-request-from-token.middleware'; import { CoreEngineModule } from './engine/core-modules/core-engine.module'; import { IntegrationsModule } from './engine/integrations/integrations.module'; @@ -79,11 +79,11 @@ export class AppModule { configure(consumer: MiddlewareConsumer) { consumer - .apply(UserWorkspaceMiddleware) + .apply(GraphQLHydrateRequestFromTokenMiddleware) .forRoutes({ path: 'graphql', method: RequestMethod.ALL }); consumer - .apply(UserWorkspaceMiddleware) + .apply(GraphQLHydrateRequestFromTokenMiddleware) .forRoutes({ path: 'metadata', method: RequestMethod.ALL }); } } diff --git a/packages/twenty-server/src/engine/middlewares/graphql-hydrate-request-from-token.middleware.ts b/packages/twenty-server/src/engine/middlewares/graphql-hydrate-request-from-token.middleware.ts new file mode 100644 index 0000000000..8e435978e4 --- /dev/null +++ b/packages/twenty-server/src/engine/middlewares/graphql-hydrate-request-from-token.middleware.ts @@ -0,0 +1,74 @@ +import { Injectable, NestMiddleware } from '@nestjs/common'; + +import { Request, Response, NextFunction } from 'express'; + +import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; +import { JwtData } from 'src/engine/core-modules/auth/types/jwt-data.type'; +import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; +import { handleExceptionAndConvertToGraphQLError } from 'src/engine/utils/global-exception-handler.util'; + +@Injectable() +export class GraphQLHydrateRequestFromTokenMiddleware + implements NestMiddleware +{ + constructor( + private readonly tokenService: TokenService, + private readonly workspaceCacheVersionService: WorkspaceCacheVersionService, + private readonly exceptionHandlerService: ExceptionHandlerService, + ) {} + + async use(req: Request, res: Response, next: NextFunction) { + const body = req.body; + + const excludedOperations = [ + 'GetClientConfig', + 'GetCurrentUser', + 'GetWorkspaceFromInviteHash', + 'Track', + 'CheckUserExists', + 'Challenge', + 'Verify', + 'SignUp', + 'RenewToken', + 'IntrospectionQuery', + ]; + + if ( + !this.tokenService.isTokenPresent(req) && + (!body?.operationName || excludedOperations.includes(body.operationName)) + ) { + return next(); + } + + let data: JwtData; + + try { + data = await this.tokenService.validateToken(req); + const cacheVersion = await this.workspaceCacheVersionService.getVersion( + data.workspace.id, + ); + + req.user = data.user; + req.workspace = data.workspace; + req.cacheVersion = cacheVersion; + } catch (error) { + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.write( + JSON.stringify({ + errors: [ + handleExceptionAndConvertToGraphQLError( + error, + this.exceptionHandlerService, + ), + ], + }), + ); + res.end(); + + return; + } + + next(); + } +} diff --git a/packages/twenty-server/src/engine/middlewares/user-workspace.middleware.ts b/packages/twenty-server/src/engine/middlewares/user-workspace.middleware.ts deleted file mode 100644 index eb7f36b832..0000000000 --- a/packages/twenty-server/src/engine/middlewares/user-workspace.middleware.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Injectable, NestMiddleware } from '@nestjs/common'; - -import { Request, Response, NextFunction } from 'express'; - -import { TokenService } from 'src/engine/core-modules/auth/services/token.service'; -import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; - -@Injectable() -export class UserWorkspaceMiddleware implements NestMiddleware { - constructor( - private readonly tokenService: TokenService, - private readonly workspaceCacheVersionService: WorkspaceCacheVersionService, - ) {} - - async use(req: Request, res: Response, next: NextFunction) { - const body = req.body; - - const excludedOperations = [ - 'GetClientConfig', - 'GetCurrentUser', - 'GetWorkspaceFromInviteHash', - 'Track', - 'CheckUserExists', - 'Challenge', - 'Verify', - 'SignUp', - 'RenewToken', - 'IntrospectionQuery', - ]; - - if ( - !this.tokenService.isTokenPresent(req) && - (!body?.operationName || excludedOperations.includes(body.operationName)) - ) { - return next(); - } - - const data = await this.tokenService.validateToken(req); - const cacheVersion = await this.workspaceCacheVersionService.getVersion( - data.workspace.id, - ); - - req.user = data.user; - req.workspace = data.workspace; - req.cacheVersion = cacheVersion; - - next(); - } -}