Skip to content

Session

Contract

@modularityjs/session defines the abstract SessionService:

typescript
interface SessionSetOptions {
  readonly ttlMs?: number;
}

abstract class SessionService {
  abstract get(id: string): Promise<SessionData | undefined>;
  abstract set(
    id: string,
    data: SessionData,
    options?: SessionSetOptions,
  ): Promise<void>;
  abstract destroy(id: string): Promise<void>;
  abstract regenerate(id: string): Promise<string>;
}

interface SessionData {
  readonly id: string;
  readonly data: Record<string, unknown>;
  readonly createdAt: number;
  readonly updatedAt: number;
}

SessionModule provides a SessionConfig with a configurable TTL in milliseconds (default: 86_400_000 / 24 hours):

typescript
import { SessionModule } from '@modularityjs/session';

SessionModule.forRoot({ ttlMs: 3_600_000 }); // 1 hour

Drivers

Memory (@modularityjs/session-memory)

Map-based in-memory session store with TTL expiration. For development and testing.

typescript
import { SessionModule } from '@modularityjs/session';
import { SessionMemoryModule } from '@modularityjs/session-memory';

const modules = [SessionModule, SessionMemoryModule];

Redis (@modularityjs/session-redis)

Redis-backed session store with automatic expiration via SET EX. Requires @modularityjs/redis.

typescript
import { SessionModule } from '@modularityjs/session';
import { SessionRedisModule } from '@modularityjs/session-redis';
import { RedisModule } from '@modularityjs/redis';

const modules = [
  RedisModule.forRoot({ host: 'localhost', port: 6379 }),
  SessionModule.forRoot({ ttlMs: 3_600_000 }),
  SessionRedisModule,
  // or with config:
  SessionRedisModule.forRoot({ keyNamespace: 'sess:' }),
];

HTTP Integration

@modularityjs/http-session wires session management into HTTP requests through the abstract HttpServer contract — it reads the session id from request.cookies and writes the cookie on the response, with no driver-specific imports. The underlying Fastify driver provides cookie parsing/serialisation via @fastify/cookie.

typescript
import { HttpModule } from '@modularityjs/http';
import { SessionModule } from '@modularityjs/session';
import { HttpFastifyModule } from '@modularityjs/http-fastify';
import { SessionMemoryModule } from '@modularityjs/session-memory';
import { HttpSessionModule } from '@modularityjs/http-session';

const modules = [
  HttpModule.forRoot({ port: 3000 }),
  HttpFastifyModule,
  SessionModule.forRoot({ ttlMs: 3_600_000 }),
  SessionMemoryModule,
  HttpSessionModule,
  // or with config:
  HttpSessionModule.forRoot({
    cookieName: 'my_sid',
    cookie: { secure: true, sameSite: 'strict' },
  }),
];

@Session() Decorator

Use the @Session() parameter decorator in controllers to access session data:

typescript
import { Inject, Injectable } from '@modularityjs/di';
import { Get } from '@modularityjs/http';
import { Session } from '@modularityjs/http-session';
import type { SessionData } from '@modularityjs/session';

@Injectable()
class ProfileController {
  @Get('/profile')
  getProfile(@Session() session: SessionData) {
    return { sessionId: session.id, data: session.data };
  }
}

HttpSessionConfig controls cookie behavior. cookieName is top-level; the rest nest under cookie:

OptionDefaultDescription
cookieName'sid'Name of the session cookie
cookie.httpOnlytruePrevents client-side JavaScript access
cookie.securetrueRequires HTTPS (override to false for local HTTP)
cookie.sameSite'lax'CSRF protection (strict, lax, none)
cookie.path'/'Cookie path
cookie.domainCookie domain (omitted by default)
rollingfalseReset cookie expiration on every response

Usage

typescript
import { Inject, Injectable } from '@modularityjs/di';
import { SessionService } from '@modularityjs/session';

@Injectable()
class AuthService {
  constructor(
    @Inject(SessionService) private readonly session: SessionService,
  ) {}

  async login(userId: string): Promise<string> {
    const now = Date.now();
    const sessionData = {
      id: crypto.randomUUID(),
      data: { userId },
      createdAt: now,
      updatedAt: now,
    };
    await this.session.set(sessionData.id, sessionData);
    return sessionData.id;
  }

  async logout(sessionId: string): Promise<void> {
    await this.session.destroy(sessionId);
  }
}