From 5cbe663bac76e0cbe796541224f8f2fd0aa1dd2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Papp?= Date: Thu, 27 Aug 2026 11:30:53 +0200 Subject: [PATCH] [client] Drop the pending session extend on a profile switch The profile-switch cleanup dropped the pending login flow and the account-prompt flag, but left extendAuthSessionFlow untouched. Its device code was issued by the previous profile's IdP client, so a WaitExtendAuthSession still parked on the browser leg would submit the resulting token against the new profile's engine. --- client/server/login_account_test.go | 8 ++++++++ client/server/server.go | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/client/server/login_account_test.go b/client/server/login_account_test.go index b8b8a1ba8..f9a7fd09b 100644 --- a/client/server/login_account_test.go +++ b/client/server/login_account_test.go @@ -103,12 +103,20 @@ func TestSwitchProfile_DropsAccountPromptAndPendingFlow(t *testing.T) { waitCancel: func() { cancelled = true }, } + extendCancelled := false + s.extendAuthSessionFlow.Set(&stubOAuthFlow{}, auth.AuthFlowInfo{DeviceCode: "device"}) + s.extendAuthSessionFlow.SetWaitCancel(func() { extendCancelled = true }) + _, err := s.SwitchProfile(ctx, nil) require.NoError(t, err) require.False(t, s.forceAccountPrompt, "the prompt flag leaked across a profile switch") require.Nil(t, s.oauthAuthFlow.flow, "the previous profile's flow leaked across a profile switch") require.Empty(t, s.oauthAuthFlow.hint) require.True(t, cancelled, "the pending wait was not cancelled") + + require.True(t, extendCancelled, "the pending extend wait was not cancelled") + _, _, pending := s.extendAuthSessionFlow.Get() + require.False(t, pending, "the previous profile's extend flow leaked across a profile switch") } func newSSOTestServer(t *testing.T, hint string, accountPrompted bool, tokenEmail string) *Server { diff --git a/client/server/server.go b/client/server/server.go index eff76fa20..8084c157f 100644 --- a/client/server/server.go +++ b/client/server/server.go @@ -1286,6 +1286,12 @@ func (s *Server) SwitchProfile(callerCtx context.Context, msg *proto.SwitchProfi s.oauthAuthFlow = oauthAuthFlow{} s.forceAccountPrompt = false + // A pending session extend belongs to the previous profile too: its device + // code was issued by that profile's IdP client, and WaitExtendAuthSession + // would submit the resulting token against the new profile's engine. + s.extendAuthSessionFlow.CancelWait() + s.extendAuthSessionFlow.Clear() + if msg != nil && msg.ProfileName != nil { s.publishProfileListChanged(*msg.ProfileName) }