-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat: implement profile-scoped OAuth for OpenAI Codex #11098
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
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.
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:
- 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.
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
})|
Не все пайплайны прошли. исправь @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 |
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.