Session Management API

Version 1.0 — October 2025

This document describes the session management and validation API endpoints added to support session expiry detection and unsafe session state handling.


Table of Contents

  1. Overview
  2. Authentication
  3. Rate Limiting
  4. Endpoints
  5. Session States
  6. Error Handling
  7. Security Considerations

Overview

The Session Management API provides endpoints for:

  • Validating the current session state
  • Manually revoking tokens for security
  • Detecting unsafe session conditions
  • Supporting GDPR/eIDAS compliance requirements

Key Features

  • Automatic Session Validation: Check if user account is still in good standing
  • Token Revocation: Manually revoke refresh tokens for security
  • Unsafe State Detection: Detect account lockouts, email verification issues
  • Comprehensive Audit Logging: All session events are logged for compliance

Authentication

All endpoints require a valid JWT access token in the Authorization header:

Authorization: Bearer <access_token>

Rate Limiting

Session Validation Endpoint

  • Limit: 30 requests per 15 minutes
  • Reason: Called periodically for monitoring (every 30 seconds)

Token Revocation Endpoint

  • Limit: 10 requests per 15 minutes
  • Reason: Sensitive security operation

Endpoints

GET /api/auth/session

Validates the current session and checks for unsafe states.

Request

GET /api/auth/session HTTP/1.1
Host: api.conformo.it
Authorization: Bearer <access_token>

Success Response (200 OK)

{
  "sessionState": "valid",
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "email": "user@example.com"
}

Error Responses

401 Unauthorized - Invalid Token

{
  "error": "Non autenticato",
  "sessionState": "invalid"
}

403 Forbidden - Account Locked

{
  "error": "Account bloccato",
  "sessionState": "account_locked",
  "lockedUntil": "2025-10-21T12:00:00.000Z"
}

403 Forbidden - Email Not Verified

{
  "error": "Email non verificata",
  "sessionState": "email_not_verified"
}

403 Forbidden - User Not Found

{
  "error": "Utente non trovato",
  "sessionState": "user_not_found"
}

Audit Logging

This endpoint logs the following events:

  • session_validated - Successful validation
  • session_expired - Account locked or email not verified

POST /api/auth/token/revoke

Manually revokes a refresh token for security purposes.

Request

POST /api/auth/token/revoke HTTP/1.1
Host: api.conformo.it
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Request Body Parameters

Parameter Type Required Description
refreshToken string Yes The refresh token to revoke

Success Response (200 OK)

{
  "message": "Token revocato con successo"
}

Error Responses

400 Bad Request - Missing Token

{
  "error": "Refresh token obbligatorio"
}

401 Unauthorized - Not Authenticated

{
  "error": "Non autenticato"
}

404 Not Found - Token Not Found

{
  "error": "Token non trovato o già revocato"
}

Audit Logging

This endpoint logs:

  • token_revoked - Successful manual revocation

Session States

Valid States

  • valid - Session is active and user account is in good standing

Invalid/Unsafe States

  • invalid - Token is missing or invalid
  • token_expired - Access token has expired (client should refresh)
  • refresh_token_expired - Refresh token has expired (re-login required)
  • refresh_token_revoked - Refresh token was revoked (re-login required)
  • account_locked - User account is temporarily locked
  • user_not_found - User account no longer exists
  • email_not_verified - User’s email is not verified
  • two_factor_pending - 2FA verification is pending

Error Handling

Client-Side Handling

The frontend axios interceptor automatically handles session expiry:

  1. Token Expired: Automatically refreshes the token and retries the request
  2. Unsafe States: Logs out the user and redirects to login with appropriate message
  3. Redirect Preservation: Saves the current location to redirect back after login

Example Client Code

import authApi from './services/authApi';

try {
  const session = await authApi.getSession();
  console.log('Session valid:', session.sessionState);
} catch (error) {
  // Axios interceptor handles this automatically
  // User will be redirected to login if needed
}

Security Considerations

Token Storage

  • Access Tokens: Stored in localStorage, short-lived (15 minutes)
  • Refresh Tokens: Stored in localStorage and database (hashed), long-lived (7 days with remember me)
  • Never expose: Tokens are never exposed in URLs or logs

Audit Logging

All session-related events are logged with:

  • User ID
  • IP address (normalized and pseudonymized)
  • User agent (truncated)
  • Timestamp
  • Event metadata

Rate Limiting

  • Prevents brute-force attacks
  • Protects against DoS
  • Per-IP and per-user limits

GDPR Compliance

  • Lawful Basis: Session data processed for contract performance (Art. 6(1)(b))
  • Data Minimization: Only necessary data collected
  • Retention: Session logs retained for 90 days
  • User Rights: Users can request session data deletion

OWASP Recommendations

A01:2021 – Broken Access Control

  • Proper authentication and authorization checks
  • Session validation before sensitive operations

A02:2021 – Cryptographic Failures

  • JWT tokens with strong secrets
  • Refresh tokens hashed in database

A05:2021 – Security Misconfiguration

  • Secure headers (Helmet.js)
  • Rate limiting enabled
  • HTTPS enforced in production

A07:2021 – Identification and Authentication Failures

  • Proper session management
  • Token expiry and rotation
  • Account lockout protection

Integration Example

Frontend Integration

import { useSessionMonitor } from './hooks/useSessionMonitor';
import SessionExpiryWarning from './components/auth/SessionExpiryWarning';

function App() {
  const { showWarning, expiresIn, extendSession } = useSessionMonitor();
  
  return (
    <>
      <YourApp />
      {showWarning && (
        <SessionExpiryWarning
          expiresIn={expiresIn}
          onExtend={extendSession}
          onLogout={() => logout()}
        />
      )}
    </>
  );
}

Autosave Integration

import { useAutosave } from './hooks/useAutosave';

function MyForm() {
  const [formData, setFormData] = useState({});
  
  useAutosave({
    data: formData,
    onSave: async (data) => {
      await api.saveProgress(data);
    },
    interval: 30000, // 30 seconds
    key: 'my-form',
  });
  
  return <form>...</form>;
}

References


Changelog

Version 1.0 (2025-10-21)

  • Initial release
  • Added session validation endpoint
  • Added token revocation endpoint
  • Added comprehensive session state handling
  • Added audit logging for session events