Fix account support for mutable workspace after login#117
Merged
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
There was a problem hiding this comment.
Pull request overview
This PR addresses accounts that are bound to an org-selected workspace so that token refresh/verification flows don’t overwrite the stored workspace binding after login.
Changes:
- Introduces helper logic to resolve whether stored
accountId/accountIdSourceshould be updated from token-derived identity. - Updates multiple flows (health check, doctor, switch, flagged recovery/verify) to use the shared identity-resolution helper.
- Expands CLI test coverage to assert org-selected workspace bindings are preserved across refresh/recovery flows.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| test/codex-manager-cli.test.ts | Adds/updates tests and mocks to validate preserving org-selected workspace binding during refresh/recovery/switch flows. |
| lib/codex-manager.ts | Centralizes account identity resolution and applies it across token refresh, flagged recovery, and sync paths to avoid overwriting org bindings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
lib/codex-manager.ts
Outdated
Comment on lines
+930
to
+932
| return { | ||
| accountId, | ||
| accountIdSource: tokenAccountId ? "token" : storedAccountIdSource, |
lib/codex-manager.ts
Outdated
| if (!account.accountId && nextAccountId) { | ||
| account.accountId = nextAccountId; | ||
| account.accountIdSource = "token"; | ||
| account.accountIdSource = account.accountIdSource ?? "token"; |
lib/codex-manager.ts
Outdated
| if (!account.accountId && tokenAccountId) { | ||
| account.accountId = tokenAccountId; | ||
| account.accountIdSource = "token"; | ||
| account.accountIdSource = account.accountIdSource ?? "token"; |
Comment on lines
+94
to
+100
| shouldUpdateAccountIdFromToken: vi.fn( | ||
| (source: string | undefined, currentAccountId: string | undefined) => { | ||
| if (!currentAccountId) return true; | ||
| if (!source) return true; | ||
| return source === "token" || source === "id_token"; | ||
| }, | ||
| ), |
ndycode
added a commit
that referenced
this pull request
Apr 6, 2026
Fix account support for mutable workspace after login
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thanks for assigning this issue to me. I'm starting to work on it and will keep this PR's description up to date as I form a plan and make progress.
Original prompt
note: greptile review for oc-chatgpt-multi-auth. cite files like
lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.Greptile Summary
this pr adds proper multi-workspace binding support by introducing
resolveStoredAccountIdentityandapplyTokenAccountIdentity, which preserveorg- andmanual-source workspace bindings across all token refresh paths (health-check,switch,autoSync,verify-flagged,doctor). previously, every refresh blindly overwroteaccountIdwith whatever the new token carried, silently downgrading an explicit org selection back to a personal token id.key changes:
resolveStoredAccountIdentitydelegates toresolveRequestAccountId+shouldUpdateAccountIdFromToken(fromlib/auth/token-utils.ts) to produce the correct id/source pair, keepingorg/manualbindings stableapplyTokenAccountIdentitywraps the above with an early-return contract and is called in five previously-inline sites acrosscodex-manager.tsstorage.ts:active: trueadded towithAccountAndFlaggedStorageTransactionstate soexportAccountscalled within that transaction reuses the snapshot; also fixes aT | null→T | undefinedtype mismatch infindCompatibleRefreshTokenMatchIndexverify-flagged,health-check,switch, andautoSyncoutstanding gaps:
runDoctororg-workspace preservation path!== undefinedvs!) betweenupsertRecoveredFlaggedAccountandapplyTokenAccountIdentityConfidence Score: 3/5
resolveStoredAccountIdentity/applyTokenAccountIdentityis architecturally correct and the previous thread'sundefined-overwrite concerns are addressed. however, therunDoctorrefresh path has no org-binding test, the project-required Windows concurrency and token-leakage documentation is absent, and a guard style inconsistency (!== undefinedvs!) inupsertRecoveredFlaggedAccountis a latent footgun ifresolveRequestAccountIdever returns an empty string.Important Files Changed
resolveStoredAccountIdentityandapplyTokenAccountIdentityto preserveorg/manualworkspace bindings across token refreshes; replaces five inline accountId-overwrite patterns. guard style inconsistency inupsertRecoveredFlaggedAccount(!== undefinedvs!) and no Windows concurrency/token-leakage documentation.active: truetowithAccountAndFlaggedStorageTransactionsoexportAccountscalled from within that transaction correctly reuses the snapshot instead of deadlocking; fixes a `TshouldUpdateAccountIdFromTokenadded.runDoctororg-binding path has no coverage.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[token refresh completes] --> B[extractAccountId from new token] B --> C[resolveStoredAccountIdentity\nstoredId, storedSource, tokenId] C --> D{resolveRequestAccountId\nreturns value?} D -- no --> E[return empty\nnextAccountId = undefined] D -- yes accountId --> F{shouldUpdateAccountIdFromToken?\nsource = org or manual} F -- no keep stored --> G[return stored accountId\n+ stored source] F -- yes token/id_token --> H{accountId === tokenAccountId?} H -- yes --> I[return accountId\nsource = token] H -- no --> J[return accountId\nsource = storedSource] E --> K[applyTokenAccountIdentity:\nguard !nextAccountId → skip write] G --> L[applyTokenAccountIdentity:\nguard same values → skip write] I --> M[applyTokenAccountIdentity:\nwrite new accountId + source] J --> M K --> N[account unchanged ✓] L --> N M --> O[account.accountId updated\nchanged = true]Comments Outside Diff (1)
lib/codex-manager.ts, line 3678-3685 (link)redundant
storageChangedFromDoctorSync = trueinside conditionalapplyTokenAccountIdentityreturnstruehere and you setstorageChangedFromDoctorSync = trueat line 3679 — but line 3685 sets it unconditionally in the same success block. the conditional at 3678-3680 is dead code: the flag is always set totrueregardless of the identity-change result, which defeats the purpose of checking the return value. compare withrunHealthCheckandautoSyncActiveAccountToCodex, which use the return value as the sole trigger for marking storage dirty.if the intent is to mark storage changed whenever a successful refresh happens (not just on identity change), then the
if (applyTokenAccountIdentity(...))block is misleading noise. either drop the innerifblock and just callapplyTokenAccountIdentitywithout capturing its return, or remove the unconditional line 3685 and add separate tracking for non-identity changes.→ should become one of these alternatives, not both:
Prompt To Fix With AI
Prompt To Fix All With AI
Last reviewed commit: 4973a20
Context used: