Skip to content

Commit 89fbea0

Browse files
sky-xoclaude
andcommitted
fix: always copy fresh auth.json for codex spawn
Previously, auth.json was only copied to the isolated ~/.june/codex/ directory on first run. After `codex auth login` refreshed tokens, the stale tokens in the isolated directory were never updated, causing authentication failures. Now always copies auth.json to pick up refreshed tokens. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1d89475 commit 89fbea0

2 files changed

Lines changed: 13 additions & 21 deletions

File tree

internal/codex/home.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,13 @@ func EnsureCodexHome() (string, error) {
2121
}
2222

2323
// Copy auth.json from user's ~/.codex/ if it exists
24+
// Always copy to pick up refreshed tokens after re-authentication
2425
userCodex := filepath.Join(home, ".codex")
2526
authSrc := filepath.Join(userCodex, "auth.json")
2627
authDst := filepath.Join(codexHome, "auth.json")
2728

28-
// Only copy if source exists and destination doesn't
29-
// Use O_CREATE|O_EXCL for atomic create-if-not-exists to avoid TOCTOU race
3029
if authData, err := os.ReadFile(authSrc); err == nil {
31-
// Try to create the file exclusively - fails if it already exists
32-
f, err := os.OpenFile(authDst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
33-
if err == nil {
34-
_, _ = f.Write(authData)
35-
f.Close()
36-
}
37-
// Ignore errors - auth.json is optional (user may not have authenticated yet)
38-
// or file already exists (which is fine - don't overwrite)
30+
_ = os.WriteFile(authDst, authData, 0600)
3931
}
4032

4133
return codexHome, nil

internal/codex/home_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,36 +81,36 @@ func TestEnsureCodexHome_NoAuthJsonOK(t *testing.T) {
8181
}
8282
}
8383

84-
func TestEnsureCodexHome_DoesNotOverwriteExistingAuthJson(t *testing.T) {
84+
func TestEnsureCodexHome_OverwritesAuthJsonWithFreshTokens(t *testing.T) {
8585
tmpDir := t.TempDir()
8686
origHome := os.Getenv("HOME")
8787
os.Setenv("HOME", tmpDir)
8888
defer os.Setenv("HOME", origHome)
8989

90-
// Create fake user codex with auth.json (source)
90+
// Create fake user codex with auth.json (source - fresh tokens)
9191
userCodex := filepath.Join(tmpDir, ".codex")
9292
os.MkdirAll(userCodex, 0755)
93-
newContent := []byte(`{"token":"new-token"}`)
94-
os.WriteFile(filepath.Join(userCodex, "auth.json"), newContent, 0600)
93+
freshContent := []byte(`{"token":"fresh-token"}`)
94+
os.WriteFile(filepath.Join(userCodex, "auth.json"), freshContent, 0600)
9595

96-
// Pre-create june codex home with existing auth.json (destination)
96+
// Pre-create june codex home with stale auth.json (destination)
9797
juneCodex := filepath.Join(tmpDir, ".june", "codex")
9898
os.MkdirAll(juneCodex, 0755)
99-
existingContent := []byte(`{"token":"existing-token"}`)
100-
os.WriteFile(filepath.Join(juneCodex, "auth.json"), existingContent, 0600)
99+
staleContent := []byte(`{"token":"stale-token"}`)
100+
os.WriteFile(filepath.Join(juneCodex, "auth.json"), staleContent, 0600)
101101

102-
// Call EnsureCodexHome - should NOT overwrite the existing auth.json
102+
// Call EnsureCodexHome - should overwrite with fresh tokens
103103
codexHome, err := EnsureCodexHome()
104104
if err != nil {
105105
t.Fatalf("EnsureCodexHome failed: %v", err)
106106
}
107107

108-
// Verify auth.json was NOT overwritten
108+
// Verify auth.json WAS overwritten with fresh tokens
109109
data, err := os.ReadFile(filepath.Join(codexHome, "auth.json"))
110110
if err != nil {
111111
t.Fatalf("failed to read auth.json: %v", err)
112112
}
113-
if string(data) != string(existingContent) {
114-
t.Errorf("auth.json was overwritten! got %q, want %q", string(data), string(existingContent))
113+
if string(data) != string(freshContent) {
114+
t.Errorf("auth.json not updated with fresh tokens: got %q, want %q", string(data), string(freshContent))
115115
}
116116
}

0 commit comments

Comments
 (0)