Version Packages - #150
Merged
Merged
Conversation
github-actions
Bot
force-pushed
the
changeset-release/main
branch
2 times, most recently
from
August 31, 2026 15:01
7c8ef65 to
a61efcb
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
September 7, 2026 23:07
a61efcb to
2785e37
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.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@seamless-auth/core@0.13.0
Minor Changes
3d64c6b: Answer 401, not 400, when nobody is signed in.
ensureCookiesgates every access-required route. When the required cookie wasabsent and there was no refresh cookie to fall back on, which is exactly the
signed-out case, it answered
400. The request was perfectly well formed. Therewas simply no session, and that is what
401means.This is a behaviour change for adopters. Anything branching on
400from an/authroute to detect a malformed request will now see401for a signed-outvisitor instead.
Two things went wrong with the old status. Every signed-out page view produced
400s, so400became ordinary background traffic in adopter logs and wouldhide a real malformed request from anyone watching. And consumers translate
status codes into words for readers:
400asks a product to say "that requestdid not come through in a form we could use" when the true sentence is "you have
been signed out, sign in again".
The neighbouring branches in the same function already answered
401for arefresh that failed and for a cookie that was invalid or expired, so this branch
was the outlier rather than the convention. All three now agree, and the status
no longer depends on which way the session happened to be absent. The response
body is unchanged.
e24dd78: Stop repeating the session credentials in the body of the response that sets them as
cookies.
Five handlers that issue session cookies returned the upstream body unchanged, and that body
carries the access token and the refresh token, because it is the same body
issueSessionCookiesreads them out of to build the cookies. So every completed sign-inanswered with
Set-Cookie: httpOnlyand then handed the same two values to the caller asJSON.
The
httpOnlyflag exists to keep those tokens out of reach of page scripts. A response bodyis not: it is readable by anything that can see the response, and it reaches places a cookie
does not, including a devtools or HAR export shared while debugging, a service worker, a
browser extension with request access, an APM tool that records payloads, and a proxy
configured to log bodies. The refresh token is the durable session credential, so it is the
half that matters.
finishRegisterHandleralready had this right, answering204with no body at all. The fivethat did not are
finishLoginHandler,verifyLoginOtpHandler,finishOAuthLoginHandler,pollMagicLinkConfirmationHandlerandswitchOrganizationHandler.Only
tokenandrefreshTokenare removed, by one exported helper rather than five copies,so the handlers cannot drift apart on it again. Everything callers actually read survives:
message,sub,email,roles,phone,organizationId,ttl,refreshTtlandreturnTo. The cookies are unchanged, so sessions work exactly as before.Nothing in
@seamless-auth/reactreads either field off a response, and its result typesalready declare them absent, with the comment that sessions are carried by cookies so
adopters have no reason to handle raw tokens. An adopter reading
tokenorrefreshTokendirectly off one of these responses, against that guidance, no longer can.
fb5c039: Forward a magic link destination to the auth API.
seamless-auth-apinow accepts an optionalredirectUrionGET /magic-link,deciding where the emailed link lands. Until now the adapters called that route with
no query, so the feature was reachable only by a backend calling the API directly. A
browser or mobile client could not use it, which was most of the point: a tenant with
both a web app and a mobile app needs each to receive a link that opens in the right
place.
RequestMagicLinkInputgains an optionalredirectUri, and both adapters read itfrom the request body of their own
POST /magic-linkand pass it through. Omit it andnothing changes: the upstream URL is exactly what it was, so no adopter has to do
anything.
The adapters forward the value rather than checking it. The auth API validates it
against the configured origins and answers
400if it is not allowed, and anallowlist that lives in two places is one that eventually disagrees with itself. A
value that is not a string is dropped rather than coerced, so it cannot turn into a
query parameter meaning something the caller did not send.
Requires an auth API that understands the parameter. Against an older one the
parameter is ignored and the link keeps the tenant-wide destination, which is the
behaviour adopters have today.
@seamless-auth/express@0.13.0
Minor Changes
e24dd78: Stop repeating the session credentials in the body of the response that sets them as
cookies.
Five handlers that issue session cookies returned the upstream body unchanged, and that body
carries the access token and the refresh token, because it is the same body
issueSessionCookiesreads them out of to build the cookies. So every completed sign-inanswered with
Set-Cookie: httpOnlyand then handed the same two values to the caller asJSON.
The
httpOnlyflag exists to keep those tokens out of reach of page scripts. A response bodyis not: it is readable by anything that can see the response, and it reaches places a cookie
does not, including a devtools or HAR export shared while debugging, a service worker, a
browser extension with request access, an APM tool that records payloads, and a proxy
configured to log bodies. The refresh token is the durable session credential, so it is the
half that matters.
finishRegisterHandleralready had this right, answering204with no body at all. The fivethat did not are
finishLoginHandler,verifyLoginOtpHandler,finishOAuthLoginHandler,pollMagicLinkConfirmationHandlerandswitchOrganizationHandler.Only
tokenandrefreshTokenare removed, by one exported helper rather than five copies,so the handlers cannot drift apart on it again. Everything callers actually read survives:
message,sub,email,roles,phone,organizationId,ttl,refreshTtlandreturnTo. The cookies are unchanged, so sessions work exactly as before.Nothing in
@seamless-auth/reactreads either field off a response, and its result typesalready declare them absent, with the comment that sessions are carried by cookies so
adopters have no reason to handle raw tokens. An adopter reading
tokenorrefreshTokendirectly off one of these responses, against that guidance, no longer can.
fb5c039: Forward a magic link destination to the auth API.
seamless-auth-apinow accepts an optionalredirectUrionGET /magic-link,deciding where the emailed link lands. Until now the adapters called that route with
no query, so the feature was reachable only by a backend calling the API directly. A
browser or mobile client could not use it, which was most of the point: a tenant with
both a web app and a mobile app needs each to receive a link that opens in the right
place.
RequestMagicLinkInputgains an optionalredirectUri, and both adapters read itfrom the request body of their own
POST /magic-linkand pass it through. Omit it andnothing changes: the upstream URL is exactly what it was, so no adopter has to do
anything.
The adapters forward the value rather than checking it. The auth API validates it
against the configured origins and answers
400if it is not allowed, and anallowlist that lives in two places is one that eventually disagrees with itself. A
value that is not a string is dropped rather than coerced, so it cannot turn into a
query parameter meaning something the caller did not send.
Requires an auth API that understands the parameter. Against an older one the
parameter is ignored and the link keeps the tenant-wide destination, which is the
behaviour adopters have today.
Patch Changes
@seamless-auth/fastify@0.4.0
Minor Changes
e24dd78: Stop repeating the session credentials in the body of the response that sets them as
cookies.
Five handlers that issue session cookies returned the upstream body unchanged, and that body
carries the access token and the refresh token, because it is the same body
issueSessionCookiesreads them out of to build the cookies. So every completed sign-inanswered with
Set-Cookie: httpOnlyand then handed the same two values to the caller asJSON.
The
httpOnlyflag exists to keep those tokens out of reach of page scripts. A response bodyis not: it is readable by anything that can see the response, and it reaches places a cookie
does not, including a devtools or HAR export shared while debugging, a service worker, a
browser extension with request access, an APM tool that records payloads, and a proxy
configured to log bodies. The refresh token is the durable session credential, so it is the
half that matters.
finishRegisterHandleralready had this right, answering204with no body at all. The fivethat did not are
finishLoginHandler,verifyLoginOtpHandler,finishOAuthLoginHandler,pollMagicLinkConfirmationHandlerandswitchOrganizationHandler.Only
tokenandrefreshTokenare removed, by one exported helper rather than five copies,so the handlers cannot drift apart on it again. Everything callers actually read survives:
message,sub,email,roles,phone,organizationId,ttl,refreshTtlandreturnTo. The cookies are unchanged, so sessions work exactly as before.Nothing in
@seamless-auth/reactreads either field off a response, and its result typesalready declare them absent, with the comment that sessions are carried by cookies so
adopters have no reason to handle raw tokens. An adopter reading
tokenorrefreshTokendirectly off one of these responses, against that guidance, no longer can.
fb5c039: Forward a magic link destination to the auth API.
seamless-auth-apinow accepts an optionalredirectUrionGET /magic-link,deciding where the emailed link lands. Until now the adapters called that route with
no query, so the feature was reachable only by a backend calling the API directly. A
browser or mobile client could not use it, which was most of the point: a tenant with
both a web app and a mobile app needs each to receive a link that opens in the right
place.
RequestMagicLinkInputgains an optionalredirectUri, and both adapters read itfrom the request body of their own
POST /magic-linkand pass it through. Omit it andnothing changes: the upstream URL is exactly what it was, so no adopter has to do
anything.
The adapters forward the value rather than checking it. The auth API validates it
against the configured origins and answers
400if it is not allowed, and anallowlist that lives in two places is one that eventually disagrees with itself. A
value that is not a string is dropped rather than coerced, so it cannot turn into a
query parameter meaning something the caller did not send.
Requires an auth API that understands the parameter. Against an older one the
parameter is ignored and the link keeps the tenant-wide destination, which is the
behaviour adopters have today.
Patch Changes