Improved
Session Management for Express SDK
3 days ago by Jim Verducci
π£ Wristband Express Auth SDK 5.0.0 Release π
New Features
β¨ Built-in Session Management (Optional)
Version 5.x introduces optional encrypted cookie-based session management powered by @wristband/typescript-session. No additional dependencies required.
Usage:
import { createWristbandAuth } from '@wristband/express-auth';
import { createWristbandSession } from '@wristband/express-auth/session';
// Wristband authentication client for handling login, callback, and logout flows.
export const wristbandAuth = createWristbandAuth({
clientId: '<WRISTBAND_CLIENT_ID>',
clientSecret: '<WRISTBAND_CLIENT_SECRET>',
wristbandApplicationVanityDomain: '<WRISTBAND_APPLICATION_VANITY_DOMAIN>',
});
// Session middleware for encrypted cookie-based session management.
export function wristbandSession() {
return createWristbandSession({
secrets: 'your-secret-key-min-32-chars',
maxAge: 3600,
secure: process.env.NODE_ENV === 'production',
});
}
// Middleware that ensures the user is authenticated and refreshes tokens if needed.
export const requireWristbandAuth = wristbandAuth.createRequireSessionAuth();import express from 'express';
import { wristbandSession } from './wristband';
const app = express();
// Initialize the session middleware for encrypted, cookie-based sessions.
app.use(wristbandSession());
// Your other application setup...import express from 'express';
import { requiresWristbandAuth } from '../wristband';
const router = express.Router();
// Apply the requiresWristbandAuth middleware to protect this route
router.get('/protected-api', requiresWristbandAuth, (req, res) => {
res.json({ message: 'This is a protected endpoint' });
});
export default router;For full documentation, see the Session Management section in README.
Note: This is entirely optional and does not affect existing applications using other session libraries like
express-session.
Breaking Changes
π UserInfo Type Improvements
The SDK now provides a structured UserInfo type that transforms raw OIDC claims into camelCase properties for better type safety and JavaScript/TypeScript conventions.
Migration:
// Before (v4.x)
const userId = userinfo.sub;
const tenantId = userinfo.tnt_id;
const identityProvider = userinfo.idp_name;
const givenName = userinfo.given_name;
// After (v5.x)
const userId = userinfo.userId;
const tenantId = userinfo.tenantId;
const identityProvider = userinfo.identityProviderName;
const givenName = userinfo.givenName;π Property Renames for Consistency
LoginConfig:
defaultTenantDomainNameβdefaultTenantName
CallbackData:
tenantDomainNameβtenantNameuserinfonow uses the newUserInfotype
LogoutConfig:
tenantDomainNameβtenantName
Migration:
// Before
await wristbandAuth.login(req, res, { defaultTenantDomainName: 'default' });
const { tenantDomainName } = callbackData;
await wristbandAuth.logout(req, res, { tenantDomainName: 'customer01' });
// After
await wristbandAuth.login(req, res, { defaultTenantName: 'default' });
const { tenantName } = callbackData;
await wristbandAuth.logout(req, res, { tenantName: 'customer01' });