Added

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() and destroy(): set the headers on the response
  • flush() and flushSync() (deferred mode): set the headers when pending session cookies are written. No headers are set if nothing is pending.
  • saveToResponse() and destroyToResponse(): the returned Response includes the headers. The original Response is not modified.
  • getCookieDataForSave() and getCookieDataForDestroy(): no headers are set, since there is no response object. Next.js already sends Cache-Control: no-store on every Server Action response.
  • Existing Cache-Control and Pragma values on the response are replaced, not merged
  • Upgrade impact: an app that sets its own Cache-Control value on a response that also saves or destroys the session now gets no-store instead

🔧 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 the Set-Cookie header, 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

These 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-session must import them from the Wristband auth SDK in use instead (e.g. import type { CallbackData } from '@wristband/express-auth')