diff --git a/client/android/client.go b/client/android/client.go index 84ed622ae..e171af5c9 100644 --- a/client/android/client.go +++ b/client/android/client.go @@ -113,10 +113,14 @@ func (c *Client) stateSnapshot() (*profilemanager.Config, string, *internal.Conn return c.config, c.cacheDir, c.connectClient } -func (c *Client) configPathSnapshot() string { +// authSnapshot returns the config together with the path it was loaded from, in +// one lock: the path identifies the profile whose account email backs the login +// hint, so reading it separately could pair one profile's config with another's +// hint when a profile switch lands in between. +func (c *Client) authSnapshot() (*profilemanager.Config, string, *internal.ConnectClient) { c.stateMu.RLock() defer c.stateMu.RUnlock() - return c.cfgPath + return c.config, c.cfgPath, c.connectClient } func (c *Client) getConnectClient() *internal.ConnectClient { diff --git a/client/android/session.go b/client/android/session.go index b1bb6a3e7..d5da09c93 100644 --- a/client/android/session.go +++ b/client/android/session.go @@ -278,7 +278,7 @@ func (c *Client) endExtend() { } func (c *Client) extendAuthSession(ctx context.Context, urlOpener URLOpener, isAndroidTV bool) error { - cfg, _, cc := c.stateSnapshot() + cfg, cfgPath, cc := c.authSnapshot() if cfg == nil || cc == nil { return fmt.Errorf("engine is not running") } @@ -296,7 +296,7 @@ func (c *Client) extendAuthSession(ctx context.Context, urlOpener URLOpener, isA // Passing the config path makes the flow pick up the login_hint: an extend // renews the session of the account already signed in, so it must not stop to // offer a choice. - a := NewAuthWithConfig(ctx, cfg, c.configPathSnapshot()) + a := NewAuthWithConfig(ctx, cfg, cfgPath) tokenInfo, err := a.foregroundGetTokenInfo(authClient, urlOpener, isAndroidTV) if err != nil { return fmt.Errorf("interactive sso login failed: %v", err)