fix: address pr-bug-scan validated finding from #1629

C1: readSystemDefaultSnapshot accepts legacy raw auth.json snapshots. C2: skip destructive system-default restore when Orca never materialized runtime credentials.
This commit is contained in:
orca-bug-scan-bot
2026-05-11 12:09:22 -07:00
parent c88287fa9a
commit 8f8d1fcb52
2 changed files with 22 additions and 2 deletions
@@ -525,6 +525,13 @@ export class ClaudeRuntimeAuthService {
const snapshotPath = this.getSystemDefaultSnapshotPath()
if (!existsSync(snapshotPath)) {
// Why: when Orca never materialized runtime credentials
// (lastWrittenCredentialsJson === null) and no snapshot exists, the
// user's system-default credentials are untouched. Deleting them here
// would log out the Claude CLI as a side-effect of a failed rollback.
if (this.lastWrittenCredentialsJson === null) {
return
}
rmSync(this.pathResolver.getRuntimePaths().credentialsPath, { force: true })
if (process.platform === 'darwin') {
await deleteActiveClaudeKeychainCredentials()
@@ -720,17 +720,30 @@ export class CodexRuntimeHomeService {
}
private readSystemDefaultSnapshot(snapshotPath: string): CodexSystemDefaultSnapshot | null {
let rawContents: string
try {
const parsed = JSON.parse(readFileSync(snapshotPath, 'utf-8')) as unknown
rawContents = readFileSync(snapshotPath, 'utf-8')
} catch {
return null
}
try {
const parsed = JSON.parse(rawContents) as unknown
if (
parsed &&
typeof parsed === 'object' &&
!Array.isArray(parsed) &&
'authJson' in parsed &&
(typeof parsed.authJson === 'string' || parsed.authJson === null)
(typeof (parsed as { authJson: unknown }).authJson === 'string' ||
(parsed as { authJson: unknown }).authJson === null)
) {
return parsed as CodexSystemDefaultSnapshot
}
// Why: pre-PR snapshots wrote raw auth.json contents verbatim. Treat any
// valid JSON object without an authJson wrapper as the legacy format so
// upgraders do not lose their system-default auth on first deselect.
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
return { authJson: rawContents }
}
} catch {
return null
}