sessions
Tracks signed-in clients in the read_user_sessions table (one row per JWT, keyed by the sid/jti claim) and exposes handlers for mine (list your sessions), revoke, and revokeAllOthers. Session creation and revocation on the hot auth path are handled by createSessionCallbacks(), wired into buildServer({ auth: { ... } }) outside the dispatcher; the feature also ships a manual-trigger cleanup job for pruning expired rows and an optional autoRevokeOnPasswordChange hook that mass-revokes all sessions for a user whenever their passwordHash changes.
Quick example
Section titled “Quick example”From recipes-session-revocation — the smallest working mount:
// Session Revocation Sample//// Shows the production-wiring shape: an app builds `createSessionCallbacks()`// against a live DB handle, then hands the creator/revoker/checker to// `buildServer({ auth: ... })`. From there the framework handles the rest —// login persists a sid, the middleware checks it on every request, logout// flips the DB row, a forged JWT without a matching session is rejected.//// What to copy into your own app://// const db = createDbConnection(config.databaseUrl);// const callbacks = createSessionCallbacks({ db });// const server = buildServer({// registry: buildRegistry([// // Pass the mass-revoker into the sessions feature to wire// // "password-change signs you out everywhere" — the feature registers// // a cross-feature entity-hook on the user entity that runs it.// createSessionsFeature({// autoRevokeOnPasswordChange: callbacks.sessionMassRevoker,// }),// // ... other features// ]),// context: { db, ... },// jwtSecret: config.jwtSecret,// auth: {// membershipQuery: "tenant:query:memberships",// loginHandler: "auth-email-password:write:login",// sessionCreator: callbacks.sessionCreator,// sessionRevoker: callbacks.sessionRevoker,// sessionChecker: callbacks.sessionChecker,// },// });//// Design rules the sample demonstrates://// 1. Sessions are a feature, not built-in. An app that doesn't register// `createSessionsFeature()` (or doesn't wire callbacks) issues plain// stateless JWTs — valid until expiry, no revocation path.// 2. Session storage is abstracted behind the three callback signatures.// This sample uses the default DB-backed impl; you could swap in a// Redis- or Memcached-backed version by wiring your own callbacks that// match `SessionCreator`/`SessionRevoker`/`SessionChecker`.// 3. The `jti` claim on the JWT is the link between stateless token and// stateful server. The middleware never trusts the JWT alone when a// checker is wired — it confirms the sid is still live.
export { createSessionCallbacks, createSessionsFeature,} from "@cosmicdrift/kumiko-bundled-features/sessions";📄 On GitHub: samples/recipes/session-revocation/src/feature.ts
How it fits
Section titled “How it fits”What this feature needs to run (Requires, top) and the write commands it provides (Provides, bottom).
flowchart TB
n_sessions["sessions"]
subgraph how_reqs["Requires"]
n_user["user"]
end
subgraph how_provides["Provides"]
n_cmd_sessions_write_user_session_revoke(["revoke"])
n_cmd_sessions_write_user_session_revoke_all_for_user(["revoke-all-for-user"])
n_cmd_sessions_write_user_session_revoke_all_others(["revoke-all-others"])
end
n_user --> n_sessions
n_sessions --> n_cmd_sessions_write_user_session_revoke
n_sessions --> n_cmd_sessions_write_user_session_revoke_all_for_user
n_sessions --> n_cmd_sessions_write_user_session_revoke_all_others
Provides — write commands this feature registers (dispatch them through the command bus):
sessions:write:user-session:revokesessions:write:user-session:revoke-all-for-usersessions:write:user-session:revoke-all-others
Getting started
Section titled “Getting started”Start with recipes-session-revocation for a step-by-step walkthrough with runnable code and integration tests.
Dependencies
Section titled “Dependencies”- Requires:
user - Activation: always on (not toggleable)
Extensions & cross-feature APIs
Section titled “Extensions & cross-feature APIs”- Exposes API:
sessions.revokeAllForUser