@setu-ts/session-plugin — cookie sessions and form CSRF
Add it: setu add session prints the registration for setu.config.ts; use
SessionPlugin({ secret: process.env.SESSION_SECRET!, csrf: {} }). It provides
CAPABILITIES.SESSION (ISessionService).
Save and read a shopping cart
import type { IRouterApi } from '@setu-ts/common';
import { getSession } from '@setu-ts/session-plugin';
export function registerCartRoutes(router: IRouterApi): void {
router.post('/cart', {
handler: (ctx) => {
getSession(ctx).set('cartId', 'cart-1');
return ctx.response.json({ ok: true });
},
});
router.get('/cart', {
handler: (ctx) => ctx.response.json({ cartId: getSession(ctx).get<string>('cartId') ?? null }),
});
}
Render a form that passes CSRF verification
import type { IRouterApi } from '@setu-ts/common';
import { csrfTokenField } from '@setu-ts/session-plugin';
export function registerCartFormRoutes(router: IRouterApi): void {
router.get('/cart/form', {
handler: (ctx) => ctx.response.html(
`<form method="post" action="/cart">${csrfTokenField(ctx)}<button>Save</button></form>`,
),
});
}
Behaviour the types do not show
- The default cookie encrypts the payload.
mode: 'sign'leaves it readable. maxAgedefaults to 7200 seconds;idleTimeoutMsuses milliseconds and is omitted by default.- Cookies default to
secure: true,httpOnly: true,sameSite: 'lax'; plain HTTP development needscookie: { secure: false }. - Missing session keys return
undefined. Nested mutations need anothersetto mark a change. csrf: {}enables verification: the default field is_csrf, the header isx-csrf-token, and safe methods are skipped. The helper follows the configured field name.- Secrets need at least 32 characters; an array rotates secrets, with index 0 sealing new cookies.
Other options
store: 'memory','cache'or anISessionStoreenables server-side payload storage.regeneraterotates the session id after a privilege change;destroylogs the session out.rollingrenews expiry;tenantBindingdefaults to true and refuses a tenant mismatch with 403.