You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sessions this CLI writes stay visible to the 3.x CLI sharing the store (#212)
## What this PR does
Sessions written by this CLI stay visible to the 3.x CLI that shares the
same auth store. Today our first write silently logs the 3.x CLI out.
Merging this closes#204.
## The bug
Both CLI lines point at one auth store (`auth.json` plus
`auth.context.json`) but disagree about its shape:
- The 3.x CLI (`@prisma/cli@latest`, 3.0.0-beta.30) reads sessions from
a top-level `tokens` array (`data.tokens || []`), selected by the
context file's `activeWorkspaceId`.
- This CLI writes `{ version, sessions, currentWorkspaceId }`, and it
writes the whole file.
Adoption of the legacy store is deliberately a pure read, so 3.x
sessions keep working until this CLI's first mutation. For someone who
only runs read commands, that first mutation is the background token
refresh. After it, 3.x reports `authenticated: false` with no error
anywhere: its reader simply finds an empty array.
## The fix
One write choke point gains a legacy mirror. `writeCredentialState`:
1. also serializes the sessions in the legacy record shape under
`tokens` (`{ workspaceId, token, refreshToken? }`), and
2. keeps `auth.context.json`'s `activeWorkspaceId` in step with
`currentWorkspaceId`, preserving the remembered-workspace name map.
Every mutation flows through this function (login, refresh, select, end
session, logout), so all of them stay legacy-visible. The mirror is
invisible to this CLI's own reader, which branches on `sessions` before
ever looking at `tokens`. This is also the behavior the code already
intended: `auth/operations.ts` carries an unwired
`storeLegacyCredential` helper written for exactly this purpose.
Hardening from the review rounds: the context file writes via temp plus
rename (a torn context makes 3.x silently self-activate its latest
session), and an empty state with no pre-existing context file does not
materialize one (an existing null pointer reads as "signed out" to 3.x,
an absent file does not).
## Proof
End-to-end against the real published 3.x binary, using a store
refreshed through `activeCredentialStorage().setTokens` (the exact write
the background refresh performs):
```
store written by main: auth whoami -> authenticated: false
store written by this branch: auth whoami -> authenticated: true, workspace wksp_e2e
```
Regression tests read the store exactly as the 3.x CLI does: refresh
keeps the session visible, create and select move the pointer,
endSession preserves or clears the legacy view, and the mirror stays
invisible to our own reader. The core two fail without the fix. Full
suite: 985 passing, `tsc --noEmit` and `pnpm lint` clean.
## Scope
Two small functions in `legacy-state.ts` (the module that owns
legacy-format knowledge) plus two lines in `writeCredentialState`. No
changes to the credential manager, the lock protocol, or the schema this
CLI reads. Known pre-existing gaps (the `project transfer` path writing
through `@prisma/credentials-store`, dead `performLogout` code) are
documented in the PR comments as follow-ups.
Fixes#204.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
0 commit comments