diff --git a/packages/twenty-server/src/engine/core-modules/auth/auth.exception.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.exception.ts index 2387ff9d31..62b215f269 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/auth.exception.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.exception.ts @@ -16,4 +16,5 @@ export enum AuthExceptionCode { UNAUTHENTICATED = 'UNAUTHENTICATED', INVALID_DATA = 'INVALID_DATA', INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR', + OAUTH_ACCESS_DENIED = 'OAUTH_ACCESS_DENIED', } diff --git a/packages/twenty-server/src/engine/core-modules/auth/controllers/google-auth.controller.ts b/packages/twenty-server/src/engine/core-modules/auth/controllers/google-auth.controller.ts index 6ae9b11d74..c674569d43 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/controllers/google-auth.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/controllers/google-auth.controller.ts @@ -9,6 +9,7 @@ import { import { Response } from 'express'; +import { AuthOAuthExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-oauth-exception.filter'; import { AuthRestApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-rest-api-exception.filter'; import { GoogleOauthGuard } from 'src/engine/core-modules/auth/guards/google-oauth.guard'; import { GoogleProviderEnabledGuard } from 'src/engine/core-modules/auth/guards/google-provider-enabled.guard'; @@ -33,6 +34,7 @@ export class GoogleAuthController { @Get('redirect') @UseGuards(GoogleProviderEnabledGuard, GoogleOauthGuard) + @UseFilters(AuthOAuthExceptionFilter) async googleAuthRedirect(@Req() req: GoogleRequest, @Res() res: Response) { const { firstName, diff --git a/packages/twenty-server/src/engine/core-modules/auth/filters/auth-oauth-exception.filter.ts b/packages/twenty-server/src/engine/core-modules/auth/filters/auth-oauth-exception.filter.ts new file mode 100644 index 0000000000..008e7d1103 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/auth/filters/auth-oauth-exception.filter.ts @@ -0,0 +1,34 @@ +import { + ArgumentsHost, + Catch, + ExceptionFilter, + InternalServerErrorException, +} from '@nestjs/common'; + +import { Response } from 'express'; + +import { + AuthException, + AuthExceptionCode, +} from 'src/engine/core-modules/auth/auth.exception'; +import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service'; + +@Catch(AuthException) +export class AuthOAuthExceptionFilter implements ExceptionFilter { + constructor(private readonly environmentService: EnvironmentService) {} + + catch(exception: AuthException, host: ArgumentsHost) { + const ctx = host.switchToHttp(); + const response = ctx.getResponse(); + + switch (exception.code) { + case AuthExceptionCode.OAUTH_ACCESS_DENIED: + response + .status(403) + .redirect(this.environmentService.get('FRONT_BASE_URL')); + break; + default: + throw new InternalServerErrorException(exception.message); + } + } +} diff --git a/packages/twenty-server/src/engine/core-modules/auth/guards/google-oauth.guard.ts b/packages/twenty-server/src/engine/core-modules/auth/guards/google-oauth.guard.ts index dd9fbf17f2..f4675888b2 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/guards/google-oauth.guard.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/guards/google-oauth.guard.ts @@ -1,6 +1,11 @@ import { ExecutionContext, Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; +import { + AuthException, + AuthExceptionCode, +} from 'src/engine/core-modules/auth/auth.exception'; + @Injectable() export class GoogleOauthGuard extends AuthGuard('google') { constructor() { @@ -14,6 +19,13 @@ export class GoogleOauthGuard extends AuthGuard('google') { const workspaceInviteHash = request.query.inviteHash; const workspacePersonalInviteToken = request.query.inviteToken; + if (request.query.error === 'access_denied') { + throw new AuthException( + 'Google OAuth access denied', + AuthExceptionCode.OAUTH_ACCESS_DENIED, + ); + } + if (workspaceInviteHash && typeof workspaceInviteHash === 'string') { request.params.workspaceInviteHash = workspaceInviteHash; } diff --git a/packages/twenty-server/src/utils/apply-cors-to-exceptions.ts b/packages/twenty-server/src/utils/apply-cors-to-exceptions.ts index 0dd3a5cc12..eba73f8e05 100644 --- a/packages/twenty-server/src/utils/apply-cors-to-exceptions.ts +++ b/packages/twenty-server/src/utils/apply-cors-to-exceptions.ts @@ -1,7 +1,7 @@ import { - ExceptionFilter, - Catch, ArgumentsHost, + Catch, + ExceptionFilter, HttpException, } from '@nestjs/common';