feat(templates): name auth cookies per application - #49
Merged
Conversation
Cookies are scoped by host and ignore the port, so two Seamless applications served from the same host share one cookie jar and overwrite each other's session. Signing into one signs you out of the other. That is invisible in production, where each application has its own domain, and unavoidable in development, where they are all on localhost. @seamless-auth/express already accepts accessCookieName, refreshCookieName, registrationCookieName and preAuthCookieName, and requireAuth accepts a matching cookieName; the templates simply never passed them. AUTH_COOKIE_PREFIX now derives all five from one value. The guard has to be told the name too. Left on its default it would look for "seamless-access" while the server had issued something else, and every request would 401 holding a valid session. The default prefix reproduces the package's own names exactly, so an existing project upgrades without logging anyone out.
Bccorb
force-pushed
the
feat/auth-cookie-prefix
branch
from
August 21, 2026 13:42
8ce3f26 to
43239a8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cookies are scoped by host and ignore the port, so two Seamless applications served from the same host share one cookie jar and overwrite each other's session. Signing into one signs you out of the other. That is invisible in production, where each application has its own domain, and unavoidable in development, where they are all on localhost.
Both API starters now read
AUTH_COOKIE_PREFIXand derive all four cookie names from it, passing them to the auth server and the matchingcookieNametorequireAuth.Why the guard has to be told too
requireAuthdefaultscookieNameindependently of the server options:Set a prefix without threading the name through and every request 401s while holding a valid session.
The default is verified byte for byte
Checked against the installed
@seamless-auth/express@0.12.0rather than from memory:A
seamless-prefix reproduces all four exactly, including registration and pre-auth sharing one name, so an existing project upgrades without logging anyone out.This makes a shipped feature work
seamless-idea-apialready writes this variable into every preview stack:Previews publish on
127.0.0.1with per-preview ports, so they are exactly the case this addresses. Until this lands the variable is set and silently ignored, and two concurrent previews sign each other out.The same code is already running in
seamless-idea-api/src/index.ts. This ports a proven pattern rather than inventing one.Known gap
Neither
template.jsonsetsAUTH_COOKIE_PREFIX, so a project scaffolded byseamless initstill gets the default names and still shares a cookie jar with its neighbours. The idea-api path is covered, the CLI path is not. Worth a follow-up to add it toenv.setwith a per-project value. Flagged in the changeset so it is not lost.Checks
npm run validatepasses.npm run check(typecheck, lint, format:check, test) andnpm run buildpass in both API starters.