No-Cache Headers for TypeScript Session SDK
📣 Wristband TypeScript Session SDK v1.0.0 Released 🎉
Release v1.0.0
Migration Guide
v1: https://github.com/wristband-dev/typescript-session/blob/main/migration/v1/README.md
General
These changes apply to all apps using the SDK, with or without Wristband.
🔧 Automatic No-Cache Headers on Session Responses
Any response that writes or deletes a session cookie now automatically includes Cache-Control: no-store and Pragma: no-cache. This prevents browsers and shared caches (such as CDNs and proxies) from storing a response that carries a user's session cookie and serving it to someone else.
Behavior:
save()anddestroy(): set the headers on the responseflush()andflushSync()(deferred mode): set the headers when pending session cookies are written. No headers are set if nothing is pending.saveToResponse()anddestroyToResponse(): the returned Response includes the headers. The original Response is not modified.getCookieDataForSave()andgetCookieDataForDestroy(): no headers are set, since there is no response object. Next.js already sendsCache-Control: no-storeon every Server Action response.- Existing
Cache-ControlandPragmavalues on the response are replaced, not merged - Upgrade impact: an app that sets its own
Cache-Controlvalue on a response that also saves or destroys the session now getsno-storeinstead
🔧 Base64url Encoding for Session Cookies
Encrypted session cookie values are now base64url-encoded (RFC 4648, Section 5) with no padding, instead of standard base64. This matches the encoding used by the Wristband auth SDKs.
- Cookie values no longer contain
+,/, or=, so they are no longer percent-encoded when written to theSet-Cookieheader, which keeps cookies smaller - Backward compatible: session cookies created by earlier versions (standard base64) are still decrypted, so existing users stay logged in after the upgrade
- Rollback impact: v0.x cannot read cookies created by v1.0.0. Rolling back after the upgrade, or sharing a session cookie with an app still on v0.x, logs out users with a new cookie once.
🗑️ Node.js 20 Support Removed
The minimum supported Node.js version is now 22.0.0 (previously 20.0.0), and the minimum npm version is now 10.5.1 (previously 9.6.0). Node.js 20 reached end of life on April 30, 2026.
Wristband-Specific
These changes only affect apps that use fromCallback() with a Wristband auth SDK.
🔧 Callback Types Match the Wristband Auth SDKs
The CallbackData, UserInfo, and UserInfoRole types used by fromCallback() now match the Wristband auth SDKs exactly. customState (in CallbackData) and customClaims (in UserInfo) are now typed as Record<string, unknown> instead of allowing any values. Runtime behavior is unchanged, and the callbackData returned by an auth SDK's callback() can still be passed directly to fromCallback().
🗑️ CallbackData, UserInfo, and UserInfoRole Type Exports
CallbackData, UserInfo, and UserInfoRole Type ExportsThese types are no longer exported from the package. They are still used by fromCallback(), but the Wristband auth SDKs export their own versions, which is where the callbackData passed to fromCallback() comes from. Runtime behavior is unchanged, and JavaScript apps are not affected.
- Code that imports any of these types from
@wristband/typescript-sessionmust import them from the Wristband auth SDK in use instead (e.g.import type { CallbackData } from '@wristband/express-auth')