Fix repeated OAuth adoption prompt for existing logins

This commit is contained in:
IanShaw027
2026-04-21 23:35:59 +08:00
parent 40f7e832b4
commit 11db3989ce
2 changed files with 150 additions and 0 deletions

View File

@@ -599,6 +599,86 @@ func TestExchangePendingOAuthCompletionLoginWithoutDecisionStillBindsIdentity(t
require.NotNil(t, storedSession.ConsumedAt)
}
func TestExchangePendingOAuthCompletionExistingLoginWithSuggestedProfileSkipsAdoptionPrompt(t *testing.T) {
handler, client := newOAuthPendingFlowTestHandler(t, false)
ctx := context.Background()
userEntity, err := client.User.Create().
SetEmail("existing-login@example.com").
SetUsername("existing-login-user").
SetPasswordHash("hash").
SetRole(service.RoleUser).
SetStatus(service.StatusActive).
Save(ctx)
require.NoError(t, err)
_, err = client.AuthIdentity.Create().
SetUserID(userEntity.ID).
SetProviderType("linuxdo").
SetProviderKey("linuxdo").
SetProviderSubject("existing-login-123").
SetMetadata(map[string]any{
"username": "existing-login-user",
}).
Save(ctx)
require.NoError(t, err)
session, err := client.PendingAuthSession.Create().
SetSessionToken("existing-login-session-token").
SetIntent("login").
SetProviderType("linuxdo").
SetProviderKey("linuxdo").
SetProviderSubject("existing-login-123").
SetTargetUserID(userEntity.ID).
SetResolvedEmail(userEntity.Email).
SetBrowserSessionKey("existing-login-browser-session-key").
SetUpstreamIdentityClaims(map[string]any{
"suggested_display_name": "Existing Login Example",
"suggested_avatar_url": "https://cdn.example/existing-login.png",
}).
SetLocalFlowState(map[string]any{
oauthCompletionResponseKey: map[string]any{
"access_token": "access-token",
"refresh_token": "refresh-token",
"expires_in": float64(3600),
"token_type": "Bearer",
"redirect": "/dashboard",
},
}).
SetExpiresAt(time.Now().UTC().Add(10 * time.Minute)).
Save(ctx)
require.NoError(t, err)
recorder := httptest.NewRecorder()
ginCtx, _ := gin.CreateTestContext(recorder)
req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/oauth/pending/exchange", nil)
req.AddCookie(&http.Cookie{Name: oauthPendingSessionCookieName, Value: encodeCookieValue(session.SessionToken)})
req.AddCookie(&http.Cookie{Name: oauthPendingBrowserCookieName, Value: encodeCookieValue("existing-login-browser-session-key")})
ginCtx.Request = req
handler.ExchangePendingOAuthCompletion(ginCtx)
require.Equal(t, http.StatusOK, recorder.Code)
payload := decodeJSONResponseData(t, recorder)
require.Equal(t, "access-token", payload["access_token"])
require.Equal(t, "refresh-token", payload["refresh_token"])
require.Equal(t, "/dashboard", payload["redirect"])
require.Equal(t, "Existing Login Example", payload["suggested_display_name"])
require.Equal(t, "https://cdn.example/existing-login.png", payload["suggested_avatar_url"])
require.NotContains(t, payload, "adoption_required")
decisionCount, err := client.IdentityAdoptionDecision.Query().
Where(identityadoptiondecision.PendingAuthSessionIDEQ(session.ID)).
Count(ctx)
require.NoError(t, err)
require.Equal(t, 1, decisionCount)
storedSession, err := client.PendingAuthSession.Get(ctx, session.ID)
require.NoError(t, err)
require.NotNil(t, storedSession.ConsumedAt)
}
func TestExchangePendingOAuthCompletionBlocksBackendModeBeforeReturningTokenPayload(t *testing.T) {
handler, client := newOAuthPendingFlowTestHandlerWithDependencies(t, oauthPendingFlowTestHandlerOptions{
settingValues: map[string]string{