Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Jan 30, 2026

Summary

Implements profile-scoped OAuth credentials for the OpenAI Codex provider, enabling users to use different OpenAI accounts for different provider profiles without manual logout/clearing sessions.

Closes #11094

Key Changes

Backend (src/)

  • oauth.ts: Core OAuth manager with profile-scoped methods

    • Changed from single key constant to profile-scoped key function using pattern openai-codex-oauth-credentials-{profileId}
    • Added Map-based in-memory credential caching per profile
    • Implemented de-duplication of concurrent token refresh requests per profile using refreshPromises Map
    • Maintained backward compatibility with legacy global methods that delegate to profile methods with no profileId
  • api.ts: Added apiConfigurationId to ApiHandlerOptions for providers that support profile-scoped authentication

  • openai-codex.ts: Updated to use profile-scoped OAuth methods

    • Added profileId property initialized from options.apiConfigurationId
    • Updated all OAuth method calls to use profile-scoped versions
  • webviewMessageHandler.ts: Updated sign-in/sign-out/rate-limits handlers to use profile-scoped methods

    • Get profile ID from message or look up from current API configuration
  • ClineProvider.ts: Updated getStateToPostToWebview to use profile-scoped auth and return openAiCodexAuthenticatedEmail

Frontend (webview-ui/)

  • vscode-extension-host.ts: Added profileId to WebviewMessage and openAiCodexAuthenticatedEmail to ExtensionState

  • OpenAICodex.tsx: Added props for email display and profileId, shows "Signed in as {email}" when authenticated

  • OpenAICodexRateLimitDashboard.tsx: Added profileId prop to pass through for rate limit requests

  • ApiOptions.tsx: Updated to extract current profile ID from state and pass new props to OpenAICodex component

Tests

  • webviewMessageHandler.spec.ts: Updated mocks to include profile-scoped methods

Testing

  • TypeScript checks pass for both src and webview-ui
  • All 22 tests in webviewMessageHandler.spec.ts pass
  • All 6 tests in openai-codex.spec.ts pass

How It Works

  1. Each provider profile can have its own OAuth session stored under a unique key
  2. When a user signs in, credentials are stored with the current profile ID
  3. When switching profiles, the UI will show the correct authentication state for that profile
  4. Users can have multiple OpenAI accounts - one per profile - without conflicts

Important

Implements profile-scoped OAuth for OpenAI Codex, enabling multiple OpenAI accounts per profile with separate credentials and session management.

  • Behavior:
    • Implements profile-scoped OAuth for OpenAI Codex, allowing different OpenAI accounts per profile without manual logout.
    • Updates openai-codex.ts, webviewMessageHandler.ts, and oauth.ts to support profile-scoped methods.
    • Adds profileId to WebviewMessage and ApiHandlerOptions for profile-specific operations.
  • Frontend:
    • Updates OpenAICodex.tsx and OpenAICodexRateLimitDashboard.tsx to handle profile-specific authentication and rate limits.
    • Displays authenticated email and rate limits per profile.
  • Tests:
    • Updates webviewMessageHandler.spec.ts to include profile-scoped OAuth method tests.
  • Misc:
    • Maintains backward compatibility with global methods in oauth.ts.

This description was created by Ellipsis for bbd0f52. You can customize this summary. It will automatically update as commits are pushed.

Implements profile-scoped OAuth credentials for the OpenAI Codex provider,
enabling users to use different OpenAI accounts for different provider profiles
without manual logout/clearing sessions.

Changes:
- oauth.ts: Add profile-scoped credential storage using profile-specific keys
  - Add Map-based in-memory caching per profile
  - Add de-duplication of concurrent token refresh requests per profile
  - Maintain backward compatibility with legacy global methods
- api.ts: Add apiConfigurationId to ApiHandlerOptions
- openai-codex.ts: Update to use profile-scoped OAuth methods
- webviewMessageHandler.ts: Update sign-in/sign-out/rate-limits handlers
- vscode-extension-host.ts: Add profileId to WebviewMessage and email to ExtensionState
- OpenAICodex.tsx: Add props for email display and profileId
- OpenAICodexRateLimitDashboard.tsx: Add profileId prop
- ClineProvider.ts: Update getStateToPostToWebview to use profile-scoped auth
- ApiOptions.tsx: Pass new props to OpenAICodex component
- webviewMessageHandler.spec.ts: Update tests for profile-scoped methods

Closes #11094
@roomote
Copy link
Contributor Author

roomote bot commented Jan 30, 2026

Rooviewer Clock   See task on Roo Cloud

All issues have been resolved. The test fix in commit bbd0f52 correctly updates the mocks to use profile-scoped OAuth methods.

  • Race condition in getAccessTokenForProfile: saveCredentialsForProfile now awaited inside async .then() callback
  • Race condition in forceRefreshAccessTokenForProfile: Same fix applied
  • Test updated to mock getAccessTokenForProfile and getAccountIdForProfile instead of legacy methods
Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

)}s, refresh_token_rotated=${rotated})`,
)
return newCreds
})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Race condition due to not awaiting saveCredentialsForProfile

The saveCredentialsForProfile call is not awaited inside the .then() callback, which can cause a race condition:

refreshPromise = refreshAccessToken(credentials).then((newCreds) => {
    this.saveCredentialsForProfile(newCreds, profileId)  // NOT AWAITED
    return newCreds
})

Problem scenario:

  1. Token refresh completes, saveCredentialsForProfile is called but not awaited
  2. The promise resolves immediately with newCreds, .finally() removes promise from Map
  3. A subsequent request (before save completes) loads stale credentials from cache/storage
  4. This could cause authentication failures or use of expired tokens

Suggested fix:

refreshPromise = refreshAccessToken(credentials).then(async (newCreds) => {
    await this.saveCredentialsForProfile(newCreds, profileId)
    return newCreds
})

The same issue exists in forceRefreshAccessTokenForProfile around line 556-564.

)}s, refresh_token_rotated=${rotated})`,
)
return newCreds
})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Same race condition as above - saveCredentialsForProfile not awaited

Same issue as in getAccessTokenForProfile:

refreshPromise = refreshAccessToken(credentials).then((newCreds) => {
    this.saveCredentialsForProfile(newCreds, profileId)  // NOT AWAITED
    return newCreds
})

Suggested fix:

refreshPromise = refreshAccessToken(credentials).then(async (newCreds) => {
    await this.saveCredentialsForProfile(newCreds, profileId)
    return newCreds
})

@loject
Copy link

loject commented Jan 30, 2026

Не все пайплайны прошли. исправь @roomote

@roomote
Copy link
Contributor Author

roomote bot commented Jan 30, 2026

Coderoo Clock   See task on Roo Cloud

Fixed the race condition bugs by moving saveCredentialsForProfile inside the async .then() callbacks. All local checks passed.

View commit | Revert commit

…nt race condition

Move saveCredentialsForProfile calls inside the .then() callbacks and make
them async/await to ensure credentials are saved as part of the promise
chain. This prevents race conditions when multiple concurrent requests
share the same refresh promise.
@loject
Copy link

loject commented Jan 30, 2026

@roomote все еще не все пайплайны прошли

@roomote
Copy link
Contributor Author

roomote bot commented Jan 30, 2026

Coderoo Clock   See task on Roo Cloud

Fixed the failing test by updating openai-codex-native-tool-calls.spec.ts to mock the new profile-scoped OAuth methods. All local checks passed.

View commit | Revert commit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Triage

Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] OpenAI (ChatGPT Plus/Pro OAuth): support multiple accounts / account switching

2 participants