From b27a52a5915228383dbdbf0a2c353452cd351d0f Mon Sep 17 00:00:00 2001 From: Elias Schneider Date: Mon, 18 May 2026 23:36:19 +0200 Subject: [PATCH] revert: delete refresh tokens on end-session to prevent reuse after logout (#1458) This reverts commit 7aacbd02456cd9043ac11ab5c09af691536fbfc6. --- backend/internal/service/oidc_service.go | 14 +--- backend/internal/service/oidc_service_test.go | 77 ------------------- 2 files changed, 1 insertion(+), 90 deletions(-) diff --git a/backend/internal/service/oidc_service.go b/backend/internal/service/oidc_service.go index 4eb4f99d..bf093bdd 100644 --- a/backend/internal/service/oidc_service.go +++ b/backend/internal/service/oidc_service.go @@ -1218,12 +1218,9 @@ func (s *OidcService) ValidateEndSession(ctx context.Context, input dto.OidcLogo return "", &common.OidcClientIdNotMatchingError{} } - tx := s.db.Begin() - defer tx.Rollback() - // Check if the user has authorized the client before var userAuthorizedOIDCClient model.UserAuthorizedOidcClient - err = tx. + err = s.db. WithContext(ctx). Preload("Client"). First(&userAuthorizedOIDCClient, "client_id = ? AND user_id = ?", clientID[0], userID). @@ -1232,11 +1229,6 @@ func (s *OidcService) ValidateEndSession(ctx context.Context, input dto.OidcLogo return "", &common.OidcMissingAuthorizationError{} } - // Delete all refresh tokens for this user - if err := tx.WithContext(ctx).Where("user_id = ?", userID).Delete(&model.OidcRefreshToken{}).Error; err != nil { - return "", err - } - // If the client has no logout callback URLs, return an error if len(userAuthorizedOIDCClient.Client.LogoutCallbackURLs) == 0 { return "", &common.OidcNoCallbackURLError{} @@ -1247,10 +1239,6 @@ func (s *OidcService) ValidateEndSession(ctx context.Context, input dto.OidcLogo return "", err } - if err := tx.Commit().Error; err != nil { - return "", fmt.Errorf("failed to commit transaction: %w", err) - } - return callbackURL, nil } diff --git a/backend/internal/service/oidc_service_test.go b/backend/internal/service/oidc_service_test.go index 57e26ebc..b7131b18 100644 --- a/backend/internal/service/oidc_service_test.go +++ b/backend/internal/service/oidc_service_test.go @@ -1303,80 +1303,3 @@ func TestPromptParameterConflicts(t *testing.T) { }) } } - -func TestOidcService_ValidateEndSession_DeletesRefreshTokens(t *testing.T) { - db := testutils.NewDatabaseForTest(t) - common.EnvConfig.EncryptionKey = []byte("0123456789abcdef0123456789abcdef") - - mockConfig := NewTestAppConfigService(&model.AppConfig{ - SessionDuration: model.AppConfigVariable{Value: "60"}, - }) - mockJwtService, err := NewJwtService(t.Context(), db, mockConfig) - require.NoError(t, err) - - oidcService := &OidcService{ - db: db, - jwtService: mockJwtService, - } - - ctx := context.Background() - userID := "test-user-123" - clientID := "test-client-456" - - userEmail := "test@example.com" - user := model.User{ - Base: model.Base{ID: userID}, - Email: &userEmail, - } - require.NoError(t, db.Create(&user).Error) - - client := model.OidcClient{ - Base: model.Base{ID: clientID}, - Name: "Test Client", - LogoutCallbackURLs: []string{"https://example.com/logout"}, - } - require.NoError(t, db.Create(&client).Error) - - authorization := model.UserAuthorizedOidcClient{ - UserID: userID, - ClientID: clientID, - } - require.NoError(t, db.Create(&authorization).Error) - - refreshToken1 := model.OidcRefreshToken{ - Token: "refresh-token-1", - UserID: userID, - ClientID: clientID, - } - require.NoError(t, db.Create(&refreshToken1).Error) - - refreshToken2 := model.OidcRefreshToken{ - Token: "refresh-token-2", - UserID: userID, - ClientID: "other-client", - } - require.NoError(t, db.Create(&refreshToken2).Error) - - userClaims := map[string]any{ - "sub": userID, - "name": "Test User", - "email": userEmail, - } - idToken, err := mockJwtService.GenerateIDToken(userClaims, clientID, "", "") - require.NoError(t, err) - - input := dto.OidcLogoutDto{ - IdTokenHint: idToken, - ClientId: clientID, - PostLogoutRedirectUri: "https://example.com/logout", - } - - callbackURL, err := oidcService.ValidateEndSession(ctx, input, userID) - require.NoError(t, err) - assert.Equal(t, "https://example.com/logout", callbackURL) - - var remainingTokens []model.OidcRefreshToken - err = db.Where("user_id = ?", userID).Find(&remainingTokens).Error - require.NoError(t, err) - assert.Empty(t, remainingTokens, "all refresh tokens for the user should be deleted") -}