Allow Claude account switches with unverified live auth (#5217)

This commit is contained in:
Jinwoo Hong 2026-06-11 14:28:29 -07:00 committed by GitHub
parent 469cbe387d
commit bf41b13cb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 9 deletions

View File

@ -2872,7 +2872,7 @@ describe('ClaudeRuntimeAuthService', () => {
expect(readFileSync(runtimeCredentialsPath, 'utf-8')).toBe(account2Credentials)
})
it('does not clobber unverified live runtime credentials when switching accounts', async () => {
it('switches accounts without persisting unverified live runtime credentials', async () => {
const runtimeCredentialsPath = join(testState.fakeHomeDir, '.claude', '.credentials.json')
const account1Original = createClaudeCredentialsJson('one@example.com', 'one-original', 'org-a')
const unverifiedLiveCredentials = createClaudeCredentialsWithoutEmail('one-live', 'org-b')
@ -2912,15 +2912,16 @@ describe('ClaudeRuntimeAuthService', () => {
writeFileSync(runtimeCredentialsPath, unverifiedLiveCredentials, 'utf-8')
settings.activeClaudeManagedAccountId = 'account-2'
await expect(service.syncForCurrentSelection()).rejects.toThrow(
'live Claude terminal has unverified refreshed auth'
)
await service.syncForCurrentSelection()
} finally {
markClaudePtyExited('live-claude-pty')
}
expect(readManagedCredentialsForTest('account-1', managedAuthPath1)).toBe(account1Original)
expect(readFileSync(runtimeCredentialsPath, 'utf-8')).toBe(unverifiedLiveCredentials)
expect(readFileSync(runtimeCredentialsPath, 'utf-8')).toBe(account2Credentials)
if (process.platform === 'darwin') {
expect(testState.scopedKeychainCredentials).toBe(account2Credentials)
}
})
it('routes refreshed Claude credentials to the matching managed account', async () => {

View File

@ -211,8 +211,12 @@ export class ClaudeRuntimeAuthService {
outgoingReadBackResult.runtimeCredentialsJson
)
} else {
throw new Error(
'Claude account switch paused because a live Claude terminal has unverified refreshed auth.'
// Why: Claude's runtime credential blob can lack enough identity
// proof to attribute a live-session refresh. Do not persist that
// unverified blob, but also do not block the user from moving new
// terminals to the selected managed account.
console.warn(
'[claude-runtime-auth] Skipping unverified live Claude auth read-back while switching accounts'
)
}
}

View File

@ -803,7 +803,7 @@ describe('ClaudeAccountService credential capture', () => {
}
const runtimeAuth = {
syncForCurrentSelection: vi.fn(async () => {
throw new Error('unverified live auth')
throw new Error('runtime sync failed')
}),
forceMaterializeCurrentSelectionForRollback: vi.fn(async () => {})
}
@ -817,7 +817,7 @@ describe('ClaudeAccountService credential capture', () => {
runtimeAuth as never
)
await expect(service.selectAccount('account-2')).rejects.toThrow('unverified live auth')
await expect(service.selectAccount('account-2')).rejects.toThrow('runtime sync failed')
expect(settings.activeClaudeManagedAccountId).toBe('account-1')
expect(settings.activeClaudeManagedAccountIdsByRuntime).toEqual({