From 69d11b8e3d61849908a7ef4d0c66fb4c0e649793 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 15 Aug 2026 20:27:37 +0200 Subject: [PATCH] Bugfix/internal server error on failed social login (#7637) * Fix internal server error on failed social login by redirecting to login page * Update changelog --- CHANGELOG.md | 6 ++++++ apps/api/src/app/auth/auth.controller.ts | 9 +++++---- apps/api/src/guards/oauth-callback.guard.ts | 21 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 apps/api/src/guards/oauth-callback.guard.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index cc1b868e0..5b26f59d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed the internal server error on a failed social login by redirecting to the login page + ## 3.52.0 - 2026-08-15 ### Added diff --git a/apps/api/src/app/auth/auth.controller.ts b/apps/api/src/app/auth/auth.controller.ts index ccf79ba99..da45f0071 100644 --- a/apps/api/src/app/auth/auth.controller.ts +++ b/apps/api/src/app/auth/auth.controller.ts @@ -2,6 +2,7 @@ import { WebAuthService } from '@ghostfolio/api/app/auth/web-auth.service'; import { AllowDuringImpersonation } from '@ghostfolio/api/decorators/allow-during-impersonation.decorator'; import { CustomThrottlerGuard } from '@ghostfolio/api/guards/custom-throttler.guard'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; +import { OAuthCallbackGuard } from '@ghostfolio/api/guards/oauth-callback.guard'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { DEFAULT_LANGUAGE_CODE } from '@ghostfolio/common/config'; import { @@ -62,13 +63,13 @@ export class AuthController { } @Get('google/callback') - @UseGuards(AuthGuard('google')) + @UseGuards(OAuthCallbackGuard('google')) @Version(VERSION_NEUTRAL) public googleLoginCallback( @Req() request: Request, @Res() response: Response ) { - const jwt: string = (request.user as any).jwt; + const jwt: string = (request.user as any)?.jwt; if (jwt) { response.redirect( @@ -98,10 +99,10 @@ export class AuthController { } @Get('oidc/callback') - @UseGuards(AuthGuard('oidc')) + @UseGuards(OAuthCallbackGuard('oidc')) @Version(VERSION_NEUTRAL) public oidcLoginCallback(@Req() request: Request, @Res() response: Response) { - const jwt: string = (request.user as any).jwt; + const jwt: string = (request.user as any)?.jwt; if (jwt) { response.redirect( diff --git a/apps/api/src/guards/oauth-callback.guard.ts b/apps/api/src/guards/oauth-callback.guard.ts new file mode 100644 index 000000000..cedbccde1 --- /dev/null +++ b/apps/api/src/guards/oauth-callback.guard.ts @@ -0,0 +1,21 @@ +import { Logger, mixin, Type } from '@nestjs/common'; +import { AuthGuard, IAuthGuard } from '@nestjs/passport'; + +export function OAuthCallbackGuard(strategy: string): Type { + class OAuthCallbackGuardMixin extends AuthGuard(strategy) { + private readonly logger = new Logger(OAuthCallbackGuard.name); + + public override handleRequest(error: Error, user: any) { + if (error) { + this.logger.error( + `Authentication with the ${strategy} strategy has failed: ${error.message}` + ); + } + + // Do not throw, the callback handler redirects to the login page instead + return user; + } + } + + return mixin(OAuthCallbackGuardMixin); +}