Skip to content

v1.9.1: fix the SuperTokens login that signed you in and left you logged out - #14

Merged
NeverEndingCode merged 1 commit into
mainfrom
v1.9.1-cookie-transport
Aug 8, 2026
Merged

v1.9.1: fix the SuperTokens login that signed you in and left you logged out#14
NeverEndingCode merged 1 commit into
mainfrom
v1.9.1-cookie-transport

Conversation

@NeverEndingCode

Copy link
Copy Markdown
Owner

Fixes the v1.9.0 regression reported in production: the GitHub button redirects to /auth/callback/github?code=… and then lands back on the login page.

What was happening

POST /auth/signinup answered status: "OK". The client reported success, replaced the URL with /, and the very next GET /api/me was a 401 — so the login screen came back with no error on it, which is why it read as "the button does nothing".

SuperTokens picks the session's token transfer method at creation time from the st-auth-mode request header, and defaults to header when it is absentsession/sessionRequestFunctions.js:

// We default to header if we can't "parse" it or if it's undefined
if (authModeHeader === "cookie") { outputTransferMethod = authModeHeader; }
else { outputTransferMethod = "header"; }

So the session came back in st-access-token / st-refresh-token response headers and no cookie was ever set. supertokens-web-js sends that header for you; v1.9.0 hand-rolled the three calls without it. That is the one frontend-SDK responsibility hand-rolling inherited silently — and the plan's own trade-off table listed "must write it" only against refresh, not against session transport.

Proved against a real SuperTokens core rather than inferred from source. Same endpoint, both ways — and note both return 200, which is why no layer reported anything:

request Set-Cookie response headers
without st-auth-mode (v1.9.0) (none) st-access-token, st-refresh-token
with st-auth-mode: cookie (this PR) sAccessToken, sRefreshToken (none)

The fix

  • st-auth-mode: cookie on POST /auth/signinup and on POST /auth/session/refresh. Cookies are right here because the app already relies on them end to end — credentials: 'include' everywhere, and the legacy JWT cookie works the same way.
  • A sign-in that sets no session now says so. If signinup succeeds but the session that follows does not exist, the login screen says the server did not set a session and suggests checking cookies. The absence of that message is the only reason this reached a production deploy: every layer reported success, so there was nothing to look at.

Testing

698 vitest (SQLite) / 724 (Postgres) / 50 smoke.

Guarded at both layers, both confirmed by mutation — renaming the header fails the unit test (expected undefined to be 'cookie') and the smoke round trip (signinup must ask for cookie transport, got undefined). The new smoke check drives the exact v1.9.0 failure: signinup fulfilled OK with no cookie, asserting the player is told rather than silently bounced.

Note

AUTH_MODE=passport + restart is the instant workaround if you need to log in before this ships — the client renders passport links in that mode and the passport routes are still registered.

🤖 Generated with Claude Code

POST /auth/signinup answered status "OK", the client reported success, the URL
went back to /, and the very next GET /api/me was a 401 - so the login screen
came back with nothing wrong on it.

SuperTokens picks the session's token transfer method at creation from the
`st-auth-mode` request header, and defaults to "header" when it is absent
(session/sessionRequestFunctions.js: "We default to header if we can't 'parse'
it or if it's undefined"). The session came back in st-access-token /
st-refresh-token response headers and no cookie was ever set.
supertokens-web-js sends that header for you; v1.9.0 hand-rolled the calls
without it. That is the one frontend-SDK responsibility hand-rolling inherited
silently.

Proved against a real core rather than from source. Same endpoint, both ways,
and BOTH return 200 - which is why no layer reported anything:

  without st-auth-mode  -> Set-Cookie: (none)   st-access-token, st-refresh-token
  with st-auth-mode:cookie -> Set-Cookie: sAccessToken, sRefreshToken

Also makes the failure impossible to ship again in silence: a sign-in the
server calls OK that is followed by no session now says so on the login screen
instead of returning a blank form. The absence of that message is the only
reason v1.9.0 reached a production deploy.

Guarded at both layers, and both confirmed by mutation - renaming the header
fails the unit test and the smoke round trip.

698 vitest SQLite / 724 Postgres / 50 smoke.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@NeverEndingCode
NeverEndingCode merged commit 45841e6 into main Aug 8, 2026
4 checks passed
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.

1 participant