# How Session Management Works in TREK: 'Remember Me' and Session Duration

> Discover TREK session management. Learn how JWT cookies, 'Remember me', and session duration work using environment variables like SESSION_DURATION.

- Repository: [Maurice/TREK](https://github.com/mauriceboe/TREK)
- Tags: internals
- Published: 2026-07-11

---

**TREK uses a JWT stored in an HTTP-only `trek_session` cookie with configurable durations—7 days for normal sessions and 30 days when "Remember me" is enabled—controlled by the `SESSION_DURATION` and `SESSION_DURATION_REMEMBER` environment variables.**

TREK implements stateless authentication using JSON Web Tokens (JWT) delivered via HTTP-only cookies. The session duration in TREK is dynamically determined by the optional "Remember me" flag passed during login, which selects between two configurable time-to-live values defined in the application's configuration.

## Configuration-Driven Session Durations

Session longevity in TREK is governed by two environment variables parsed in [`server/src/config.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/config.ts) (lines 151-176):

- **`SESSION_DURATION`** – Defines the standard session length when "Remember me" is unchecked. Defaults to `7d` (7 days).
- **`SESSION_DURATION_REMEMBER`** – Defines the extended session length when "Remember me" is checked. Defaults to `30d` (30 days).

These values are converted into both human-readable constants and millisecond/second representations for use across the application. If the environment variables cannot be parsed, the system falls back to the defaults.

## The Authentication Flow

When a user authenticates, TREK coordinates between the login controller, authentication service, and cookie utility to establish the session with the correct duration.

### Login Request Handling

The login controller in [`server/src/nest/auth/auth-public.controller.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/nest/auth/auth-public.controller.ts) extracts the optional **`remember_me`** boolean from the request body. This flag is passed downstream to determine which session duration to apply.

```typescript
// Controller receives the flag
const { email, password, remember_me } = body;
const remember = remember_me === true;

```

If omitted, the flag defaults to `false`, resulting in a session-only cookie that expires when the browser closes.

### JWT Token Generation

In [`server/src/nest/auth/auth.service.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/nest/auth/auth.service.ts), the `generateToken()` function creates the JWT with an expiration claim matching the selected duration:

```typescript
export function generateToken(
  user: { id: number | bigint; password_version?: number }, 
  rememberMe = false
) {
  const expiresIn = rememberMe 
    ? SESSION_DURATION_REMEMBER_SECONDS 
    : SESSION_DURATION_SECONDS;
  
  return jwt.sign(
    { sub: user.id, pv: user.password_version ?? 0 }, 
    JWT_SECRET, 
    { expiresIn }
  );
}

```

The token's `exp` claim mirrors the configuration, ensuring the JWT expires simultaneously with the cookie.

### Cookie Creation and Secure Flag

The [`server/src/services/cookie.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/services/cookie.ts) file contains the `setAuthCookie()` helper and `resolveMaxAge()` logic that maps the remember flag to cookie behavior:

```typescript
function resolveMaxAge(remember: RememberOption): { maxAge: number } | Record<string, never> {
  if (remember === false) return {};                              // session cookie
  if (remember === true)  return { maxAge: SESSION_DURATION_REMEMBER_MS };
  return { maxAge: SESSION_DURATION_MS };                         // default persistent
}

```

The **`trek_session`** cookie is configured with the following security characteristics:

- **HTTP-only** – Prevents JavaScript access to the cookie.
- **Secure flag** – Determined by three conditions in `cookieOptions()` (lines 30-38):
  1. Disabled if `COOKIE_SECURE=false` (useful for LAN testing).
  2. Enabled if `NODE_ENV=production` or `FORCE_HTTPS=true`.
  3. Enabled if `req.secure` indicates HTTPS (respecting `X-Forwarded-Proto` when Express trusts the proxy).

If a Secure cookie would be sent over plain HTTP, the `willDropSecureCookie()` function (lines 58-67) detects this condition and surfaces a warning to the user, suggesting they either use HTTPS or set `COOKIE_SECURE=false`.

## Practical Implementation Examples

### Login with "Remember me" Enabled

```typescript
// Client request
await fetch('/api/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email, password, remember_me: true })
});

// Server processing
const remember = remember_me === true;
const token = generateToken(user, remember);
setAuthCookie(res, token, req, remember); // Uses SESSION_DURATION_REMEMBER (30 days)

```

### Login with Session-Only Cookie

```typescript
// Client request without remember_me flag
await fetch('/api/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email, password })
});

// Server processing
const remember = false; // Default when omitted
const token = generateToken(user, remember);
setAuthCookie(res, token, req, remember); // No maxAge set; cookie expires on browser close

```

### Checking Configuration Values

```typescript
import { SESSION_DURATION, SESSION_DURATION_REMEMBER } from '../config';

console.log(`Normal session: ${SESSION_DURATION}`);           // "7d"
console.log(`Remember-me session: ${SESSION_DURATION_REMEMBER}`); // "30d"

```

## Summary

- **Dual duration system**: TREK distinguishes between regular sessions (`7d` default) and "Remember me" sessions (`30d` default) via environment variables.
- **JWT-cookie synchronization**: The JWT `exp` claim and cookie `maxAge` are always set to the same duration to prevent token-cookie mismatches.
- **Three-state logic**: The `remember` parameter supports `true` (extended), `false` (session-only), and `undefined` (historic default persistent).
- **Security-first cookies**: The Secure flag automatically enables in production or HTTPS environments, with detection for misconfigured HTTP deployments.
- **Key files**: Configuration resides in [`server/src/config.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/config.ts), cookie logic in [`server/src/services/cookie.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/services/cookie.ts), and token generation in [`server/src/nest/auth/auth.service.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/nest/auth/auth.service.ts).

## Frequently Asked Questions

### How do I change the default session duration in TREK?

Set the `SESSION_DURATION` environment variable to your desired duration string (e.g., `1d`, `12h`, `60s`). For "Remember me" durations, use `SESSION_DURATION_REMEMBER`. These values are parsed in [`server/src/config.ts`](https://github.com/mauriceboe/TREK/blob/main/server/src/config.ts) and converted to milliseconds for cookies and seconds for JWTs.

### What happens if I check "Remember me" on a public computer?

The browser receives a persistent cookie with a `maxAge` of 30 days (or your configured `SESSION_DURATION_REMEMBER`). The cookie remains valid across browser restarts. To invalidate the session, you must either log out through the application or clear the browser's cookies for the domain.

### Why is my TREK session cookie disappearing immediately after login?

If the server is configured with `COOKIE_SECURE` enabled (the default in production) but you are accessing it over HTTP, the browser silently drops the Secure cookie. Check the server logs for warnings from `willDropSecureCookie()`, or explicitly set `COOKIE_SECURE=false` for local development. Alternatively, ensure you are serving the application over HTTPS.

### How does TREK validate sessions on subsequent requests?

TREK extracts the JWT from the `trek_session` cookie and verifies its signature and expiration using the `JWT_SECRET`. The `password_version` claim in the token allows for immediate invalidation of all sessions if the user's password is changed, as implemented in the authentication middleware.