Skip to content

fix: atomically rewrite auth_token + identity on login#468

Merged
tomasz-tomczyk merged 2 commits intomainfrom
fix/atomic-auth-login
May 5, 2026
Merged

fix: atomically rewrite auth_token + identity on login#468
tomasz-tomczyk merged 2 commits intomainfrom
fix/atomic-auth-login

Conversation

@tomasz-tomczyk
Copy link
Copy Markdown
Owner

@tomasz-tomczyk tomasz-tomczyk commented May 5, 2026

Summary

  • Login persisted credentials in two separate saveGlobalConfig calls (saveAuthToken then saveAuthIdentity), leaving a window where a crash between writes could pair a fresh token with stale identity from the previous account — the failure mode that surfaced feat: send + cache verified author identity on share #371. Collapse them into one saveAuthSession closure that rewrites all four auth_* fields in a single atomic temp+rename under the existing flock.
  • Drop saveAuthToken, saveAuthIdentity, and removeAuthToken — none have production callers anymore. clearAuthIdentity already owns logout / 401, and lazyBackfillAuthUserID keeps its own narrower closure for the legitimate identity-only backfill path.
  • Document the consolidation decision behind closing Consolidate overlapping author/identity fields in config #392 — the two visible name fields (author, auth_user_name) stay; author is the documented local pen name, auth_user_name is opaque session metadata. The atomic-write fix here resolves the underlying feat: send + cache verified author identity on share #371 class without needing to consolidate config keys.

Closes #392.

Review

  • Code review: passed (go-expert)
  • Intent audit: clean
  • Parity audit: N/A (no review-page surface)

Test plan

  • Unit: TestSaveAuthSession_AtomicRewrite, TestSaveAuthSession_RemovesFieldsAbsentFromResponse — cover the bearer + identity rewrite atomically (including partial-server-response field removal).
  • Integration (make e2e-share): TestAuthSessionReLoginEndToEnd seeds two distinct users on crit-web, persists user A's session via saveAuthSession, re-persists as user B, runs crit share with HOME pointing at the test home (no CRIT_AUTH_TOKEN env override) and asserts the server stamps user B on the resulting comment.
  • Verified locally: go test -race -count=1 ./... and the share integration suite both pass.

🤖 Generated with Claude Code

Login persisted credentials in two separate saveGlobalConfig calls
(saveAuthToken then saveAuthIdentity), leaving a window where a crash
between writes could pair a fresh token with stale identity from the
prior account — the failure mode that surfaced #371. Collapse them
into one saveAuthSession closure that writes all four auth_* fields
in a single atomic temp+rename.

Test plan
- Unit: TestSaveAuthSession_AtomicRewrite, _RemovesFieldsAbsentFromResponse
- Integration (e2e-share): TestAuthSessionReLoginEndToEnd seeds two
  users on crit-web, persists user A then user B via saveAuthSession,
  runs `crit share` with HOME pointed at the test home (no
  CRIT_AUTH_TOKEN env override), and asserts the server stamps user B
  on the resulting comment.
These three helpers no longer have any production callers — saveAuthSession
is the sole login-persistence path, clearAuthIdentity owns logout/401, and
lazyBackfillAuthUserID writes its own narrower closure. The remaining tests
exercised them in isolation, which means they passed forever regardless of
whether anything called them. Repoint the two TestSaveGlobalConfig_* cases
at saveAuthSession (which still exercises saveGlobalConfig under the hood),
and drop TestSaveAndRemoveAuthToken plus the TestSaveAuthIdentity_* pair —
TestSaveAuthSession_AtomicRewrite and _RemovesFieldsAbsentFromResponse cover
the same ground plus auth_token.
@tomasz-tomczyk tomasz-tomczyk merged commit f9eb8a6 into main May 5, 2026
6 checks passed
@tomasz-tomczyk tomasz-tomczyk deleted the fix/atomic-auth-login branch May 5, 2026 21:31
@codecov
Copy link
Copy Markdown

codecov Bot commented May 5, 2026

Codecov Report

❌ Patch coverage is 50.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.15%. Comparing base (d7a9e4b) to head (3b2f4d4).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
auth.go 50.00% 2 Missing ⚠️

❌ Your patch status has failed because the patch coverage (50.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #468      +/-   ##
==========================================
- Coverage   69.15%   69.15%   -0.01%     
==========================================
  Files          36       36              
  Lines       10749    10736      -13     
==========================================
- Hits         7434     7425       -9     
+ Misses       2749     2746       -3     
+ Partials      566      565       -1     
Flag Coverage Δ
e2e 32.42% <0.00%> (+0.03%) ⬆️
unit 66.68% <50.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consolidate overlapping author/identity fields in config

1 participant