Skip to main content

Authentication Testing Runbook (Manual)

1. Overview

This document outlines the sequential testing flow for the Reshma-Core Two-Token Authentication system. These tests verify both the "Happy Path" (expected behavior) and critical security edge cases.

Recommended Tools: Thunder Client (VS Code) or Postman.
Note: These tools are required over cURL because they automatically manage the HttpOnly refresh cookies necessary for session testing.


2. Prerequisites & Environment Setup

Before beginning the test suite, verify the infrastructure is actively running:

  1. MongoDB: Running locally or via Atlas.
  2. Redis: Running locally (redis-cli ping -> PONG).
  3. Background Workers: Ensure npm run dev has booted both the Express server AND the BullMQ email worker.
  4. Base URL: http://localhost:5000/api/v1

3. The "Happy Path" (Sequential Test Suite)

These tests MUST be executed in this exact order, as each step relies on the state generated by the previous step.

Test 1: Account Registration

  • Action: Send POST /auth/register
  • Payload (JSON):
    {
    "firstname": "Test",
    "lastname": "User",
    "email": "test@example.com",
    "password": "SecurePassword123!"
    }
  • Expected Result: 201 Created.
  • Side-Effect Verification:
    1. Check the server terminal: The Winston logger should print the generated 6-digit OTP.
    2. Check MongoDB: The user document should exist with isEmailVerified: false.

Test 2: OTP Verification (Session Grant)

  • Action: Send POST /auth/verify-otp
  • Payload (JSON):
    {
    "email": "test@example.com",
    "otp": "123456" // Replace with OTP from Test 1
    }
  • Expected Result: 200 OK. The JSON response must contain the user object and the accessToken.
  • Side-Effect Verification:
    1. CRITICAL: Check the "Cookies" tab in Thunder Client. A refreshToken cookie MUST be present.
    2. Check Redis: GET otp:test@example.com should return nil (OTP deleted to prevent replay attacks).
    3. Check MongoDB: User isEmailVerified should now be true.

Test 3: Standard Login

  • Action: Send POST /auth/login
  • Payload (JSON):
    {
    "email": "test@example.com",
    "password": "SecurePassword123!"
    }
  • Expected Result: 200 OK. Receives a new accessToken.

Test 4: Silent Token Refresh

  • Action: Send GET /auth/refresh (No Body, No Auth Headers).
  • Expected Result: 200 OK. The server reads the HttpOnly cookie automatically and returns a brand new accessToken in the JSON response.

Test 5: Secure Logout

  • Action: Send GET /auth/logout
  • Headers: Authorization: Bearer <PASTE_ACCESS_TOKEN_HERE>
  • Expected Result: 200 OK.
  • Side-Effect Verification:
    1. Check the "Cookies" tab: The refreshToken should be overwritten with "loggedout" and expired.
    2. Check Redis: Run KEYS *. You should see a new key prefixed with blacklist:, proving the session is permanently burned.

4. Security & Edge Case Testing (Negative Tests)

These tests ensure the API fails gracefully and securely under malicious or incorrect conditions.

Edge Case 1: Zod Payload Firewall

  • Action: Send POST /auth/register with an invalid email (test@com) and a weak password (123).
  • Expected Result: 400 Bad Request. The response message must clearly list both the email format error and the password strength error.

Edge Case 2: Unverified Login Block

  • Action: Register a completely new email (Test 1), but do not verify the OTP. Attempt to call POST /auth/login with those credentials.
  • Expected Result: 403 Forbidden with the message: "Please verify your email address before logging in."

Edge Case 3: Replay Attack Prevention

  • Action: Attempt to call POST /auth/verify-otp using an OTP that has already been successfully verified.
  • Expected Result: 400 Bad Request with "Invalid or expired OTP."

Edge Case 4: Protected Route Gateway (Missing Token)

  • Action: Call GET /auth/logout but do not provide the Bearer token in the Auth tab.
  • Expected Result: 401 Unauthorized with "You are not logged in".

Edge Case 5: The Blacklist Check

  • Action:

    1. Login successfully.
    2. Logout successfully (this blacklists the refresh token).
    3. Manually re-add the old refreshToken back into Thunder Client's cookie tab.
    4. Call GET /auth/refresh.
  • Expected Result: 401 Unauthorized with "Session revoked." (Proves the Redis blacklist is actively protecting the route).