A dev sign-in can never act on an Atmosphere account #211
No reviewers
Labels
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/Ponente!211
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix-dev-login-never-writes-network"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Urgent — this is what wrote to a real Bluesky profile today.
/dev/loginstored no token, and that was the whole guarantee. But the token store is keyed by DID, not by session, and the DID the e2e suite signs in as is a real account (did:plc:vmdq…, grandiras.net). Once that account had signed in for real on the local test stack, its OAuth token was in the store, every dev session as that DID read it as its own, andprofile.spec.js's "Ponente only" save wrote a test display name and a one-pixel avatar onto the account's real Bluesky profile.What changes:
/dev/loginstamps its session with a claim (Auth/DevSignIn.cs).ProfileServicetreats a stamped session as holding no token and no client, whatever the store says. Both the token read and the client factory call are guarded. It is the only place in the app that builds an Atmosphere client from the signed-in member.DevSignInTestspins it: a write-scoped token sits in the store, a dev session saves to the network, and the result isNotPermittedwith the client factory never asked.profile.spec.jsasserts the network option is disabled and picks the Ponente target explicitly before it types anything. Neither half alone stands between the suite and somebody's profile.docs/auth.mdanddocs/testing.mdsay why.No member-visible change;
/dev/loginonly exists in Development.🤖 Generated with Claude Code
🤖 Reviewing this PR — the review will link the full session transcript.
✅ Verdict: approve — no blocking issues found.
Good fix for a real incident. The claim-based approach is the right one — the question "how did this session sign in" is only answerable from the session, and the cookie is server-signed so the claim can't be forged. Both
/dev/loginpaths (member and?handle=stranger) stampDevSignIn.Claim, andProfileService— verified as the only place in the app that builds an Atmosphere client from the signed-in member — guards both the token read (HeldTokenAsync) and the client factory call.DevSignInTestspins the exact incident state: a write-scoped token in the store beside a dev session yieldsNotPermittedwith the factory never asked, and the network path refuses before touchingmembers/avatars/resolver, so the null! placeholders are safe. The e2e spec now asserts the Network radio is disabled and picks Ponente explicitly before typing, both of which fail loudly rather than silently if the guarantee regresses. Docs updated consistently. No issues found.⏱ 1m 15s · 4 steps · $0.0065 · tokens: 33.0k in / 906 out (+36.5k cache-read) · Go: 5h 3% · wk 1% · mo 33%
📜 Full session transcript