feat: implement profile-scoped OAuth for OpenAI Codex - #11098
Conversation
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
All issues have been resolved. The test fix in commit bbd0f52 correctly updates the mocks to use profile-scoped OAuth methods.
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 | ||
| }) |
There was a problem hiding this comment.
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:
- Token refresh completes,
saveCredentialsForProfileis called but not awaited - The promise resolves immediately with
newCreds,.finally()removes promise from Map - A subsequent request (before save completes) loads stale credentials from cache/storage
- 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 | ||
| }) |
There was a problem hiding this comment.
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
})|
Не все пайплайны прошли. исправь @roomote |
Fixed the race condition bugs by moving |
…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.
|
@roomote все еще не все пайплайны прошли |
Fixed the failing test by updating |
|
@roomote можешь закрыть PR? Я сделал свой |
PR closed as requested. @loject mentioned they have created their own implementation. |
|
Closing as requested by @loject who has created their own implementation. |
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
openai-codex-oauth-credentials-{profileId}api.ts: Added
apiConfigurationIdtoApiHandlerOptionsfor providers that support profile-scoped authenticationopenai-codex.ts: Updated to use profile-scoped OAuth methods
profileIdproperty initialized fromoptions.apiConfigurationIdwebviewMessageHandler.ts: Updated sign-in/sign-out/rate-limits handlers to use profile-scoped methods
ClineProvider.ts: Updated
getStateToPostToWebviewto use profile-scoped auth and returnopenAiCodexAuthenticatedEmailFrontend (webview-ui/)
vscode-extension-host.ts: Added
profileIdto WebviewMessage andopenAiCodexAuthenticatedEmailto ExtensionStateOpenAICodex.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
Testing
How It Works
Important
Implements profile-scoped OAuth for OpenAI Codex, enabling multiple OpenAI accounts per profile with separate credentials and session management.
openai-codex.ts,webviewMessageHandler.ts, andoauth.tsto support profile-scoped methods.profileIdtoWebviewMessageandApiHandlerOptionsfor profile-specific operations.OpenAICodex.tsxandOpenAICodexRateLimitDashboard.tsxto handle profile-specific authentication and rate limits.webviewMessageHandler.spec.tsto include profile-scoped OAuth method tests.oauth.ts.This description was created by
for bbd0f52. You can customize this summary. It will automatically update as commits are pushed.