test-auth-wrapper

Expert knowledge on CLI testing with auth bypass, automated endpoint testing, and the 3 bypass methods (headers, environment, test headers). Use this skill when user asks about "test endpoint", "cli testing", "auth bypass", "curl", "automated testing", "local development", or "testing without clerk".

allowed_tools: Read, Bash, Grep

$ Installer

git clone https://github.com/Sanchay-T/influencer-platform-app /tmp/influencer-platform-app && cp -r /tmp/influencer-platform-app/small-fixes/.claude/skills/test-auth-wrapper ~/.claude/skills/influencer-platform-app

// tip: Run this command in your terminal to install the skill


name: test-auth-wrapper description: Expert knowledge on CLI testing with auth bypass, automated endpoint testing, and the 3 bypass methods (headers, environment, test headers). Use this skill when user asks about "test endpoint", "cli testing", "auth bypass", "curl", "automated testing", "local development", or "testing without clerk". allowed-tools: Read, Bash, Grep

Test Auth Wrapper Expert

You are an expert in testing API endpoints locally without full Clerk authentication. This skill provides knowledge about the 3 auth bypass methods and CLI testing patterns.

When To Use This Skill

This skill activates when users:

  • Need to test endpoints from CLI or scripts
  • Want to bypass Clerk auth for local development
  • Write automated tests for API routes
  • Debug endpoints without browser session
  • Run scripts that call internal APIs
  • Perform integration testing

Core Knowledge

The 3 Auth Bypass Methods

Bypass Resolution (from /lib/auth/get-auth-or-test.ts):

  1. Test Headers (Highest Priority)
  2. Dev Bypass Header
  3. Environment Bypass
  4. Clerk Auth (Fallback)

Method 1: Test Headers

Use Case: Automated tests, CI/CD

Headers:

  • x-test-user-id: User ID to impersonate
  • x-test-email: Email (optional)

Example:

curl http://localhost:3000/api/campaigns \
  -H "x-test-user-id: user_2abc123xyz" \
  -H "x-test-email: test@example.com"

Implementation:

// In /lib/auth/get-auth-or-test.ts
const payload = verifyTestAuthHeaders(headerStore);
if (payload?.userId) {
  return {
    userId: payload.userId,
    sessionId: `test_${payload.userId}`,
    sessionClaims: payload.email ? { email: payload.email } : undefined,
  };
}

Advantages:

  • Works in any environment
  • Per-request control
  • No config files needed
  • Easy to test different users

Disadvantages:

  • Must add headers to every request

Method 2: Dev Bypass Header

Use Case: Manual CLI testing, Postman

Headers:

  • x-dev-auth: dev-bypass (token must match AUTH_BYPASS_TOKEN)
  • x-dev-user-id: User ID (optional, falls back to AUTH_BYPASS_USER_ID)
  • x-dev-email: Email (optional, falls back to AUTH_BYPASS_EMAIL)

Environment Variables:

# .env.local
AUTH_BYPASS_TOKEN=dev-bypass  # Default if not set
AUTH_BYPASS_HEADER=x-dev-auth  # Default if not set
AUTH_BYPASS_USER_ID=user_2abc123xyz  # Fallback user
AUTH_BYPASS_EMAIL=dev@example.com  # Fallback email

Example:

curl http://localhost:3000/api/campaigns \
  -H "x-dev-auth: dev-bypass"
# Uses AUTH_BYPASS_USER_ID from .env.local

curl http://localhost:3000/api/campaigns \
  -H "x-dev-auth: dev-bypass" \
  -H "x-dev-user-id: user_different123"
# Overrides with specific user

Implementation:

const defaultBypassToken = process.env.AUTH_BYPASS_TOKEN || 'dev-bypass';
const bypassHeaderName = process.env.AUTH_BYPASS_HEADER?.toLowerCase() || 'x-dev-auth';

if (
  process.env.NODE_ENV !== 'production' &&
  headerStore.get(bypassHeaderName) === defaultBypassToken
) {
  const userIdFromHeader = headerStore.get('x-dev-user-id') || process.env.AUTH_BYPASS_USER_ID;
  return {
    userId: userIdFromHeader,
    sessionId: 'bypass',
    sessionClaims: { /* ... */ }
  };
}

Advantages:

  • Configurable token for security
  • Default user from .env
  • Easy to change user per-request
  • Good for Postman collections

Disadvantages:

  • Requires .env setup
  • Only works in non-production

Method 3: Environment Bypass

Use Case: Long dev sessions, scripts

Environment Variables:

# .env.local
ENABLE_AUTH_BYPASS=true
AUTH_BYPASS_USER_ID=user_2abc123xyz
AUTH_BYPASS_EMAIL=dev@example.com  # Optional

Example:

# No headers needed!
curl http://localhost:3000/api/campaigns

curl -X POST http://localhost:3000/api/campaigns \
  -H "Content-Type: application/json" \
  -d '{"name":"Test","searchType":"instagram-reels"}'

Implementation:

const bypassEnabled = process.env.ENABLE_AUTH_BYPASS === 'true';
const bypassUserId = process.env.AUTH_BYPASS_USER_ID;

if (bypassEnabled && bypassUserId && process.env.NODE_ENV !== 'production') {
  return {
    userId: bypassUserId,
    sessionId: 'bypass',
    sessionClaims: { /* ... */ }
  };
}

Advantages:

  • No headers needed
  • Fastest for dev
  • Works for all requests automatically

Disadvantages:

  • Can't test different users without restart
  • Easy to forget it's enabled
  • Must disable for Clerk testing

Common Patterns

Pattern 1: Testing Endpoint with curl

# Quick test with dev bypass
curl http://localhost:3000/api/billing/status \
  -H "x-dev-auth: dev-bypass"

# Test specific user
curl http://localhost:3000/api/billing/status \
  -H "x-test-user-id: user_2abc123xyz"

# POST with JSON body
curl -X POST http://localhost:3000/api/campaigns \
  -H "x-dev-auth: dev-bypass" \
  -H "Content-Type: application/json" \
  -d '{"name":"Test Campaign","searchType":"instagram-reels","keywords":["fitness"]}'

# DELETE endpoint
curl -X DELETE http://localhost:3000/api/campaigns/xxx-xxx-xxx \
  -H "x-dev-auth: dev-bypass"

Pattern 2: Node Script Testing

// scripts/test-endpoint.js
require('dotenv').config({ path: '.env.local' });

async function testEndpoint() {
  const response = await fetch('http://localhost:3000/api/campaigns', {
    headers: {
      'x-dev-auth': 'dev-bypass',
      'x-dev-user-id': 'user_2abc123xyz'
    }
  });

  const data = await response.json();
  console.log('Response:', data);
}

testEndpoint();

Run: node scripts/test-endpoint.js

Pattern 3: Automated Test Suite

// tests/api/campaigns.test.ts
import { describe, it, expect } from 'vitest';

const BASE_URL = 'http://localhost:3000';
const TEST_USER_ID = 'user_test123';

describe('Campaigns API', () => {
  it('should create campaign', async () => {
    const response = await fetch(`${BASE_URL}/api/campaigns`, {
      method: 'POST',
      headers: {
        'x-test-user-id': TEST_USER_ID,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: 'Test Campaign',
        searchType: 'instagram-reels',
        keywords: ['fitness']
      })
    });

    expect(response.status).toBe(201);
    const data = await response.json();
    expect(data.success).toBe(true);
    expect(data.data.name).toBe('Test Campaign');
  });

  it('should enforce plan limits', async () => {
    // Create user with limit of 3 campaigns
    // ... create 3 campaigns ...

    // 4th should fail
    const response = await fetch(`${BASE_URL}/api/campaigns`, {
      method: 'POST',
      headers: {
        'x-test-user-id': TEST_USER_ID,
        'x-plan-bypass': 'none', // Don't bypass plan limits
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: 'Campaign 4',
        searchType: 'instagram-reels'
      })
    });

    expect(response.status).toBe(403);
    const data = await response.json();
    expect(data.error).toContain('limit');
  });
});

Pattern 4: Plan Bypass (Testing Without Limits)

# Bypass campaign limits
curl -X POST http://localhost:3000/api/campaigns \
  -H "x-dev-auth: dev-bypass" \
  -H "x-plan-bypass: campaigns" \
  -H "Content-Type: application/json" \
  -d '{"name":"Test","searchType":"instagram-reels"}'

# Bypass all limits
curl -X POST http://localhost:3000/api/campaigns \
  -H "x-dev-auth: dev-bypass" \
  -H "x-plan-bypass: all"

# Via environment (for scripts)
# .env.local
PLAN_VALIDATION_BYPASS=all  # or "campaigns,creators"

Anti-Patterns (Avoid These)

Anti-Pattern 1: Hardcoding User IDs in Code

// BAD: Hardcoded test user
export async function POST(req: Request) {
  const userId = 'user_2abc123xyz'; // WRONG!
  // ...
}

Why it's bad: Breaks production, not flexible

Do this instead:

// GOOD: Use auth resolver
const auth = await getAuthOrTest();
if (!auth?.userId) {
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}

Anti-Pattern 2: Leaving Bypass Enabled in Production

// BAD: No environment check
if (process.env.ENABLE_AUTH_BYPASS === 'true') {
  return { userId: process.env.AUTH_BYPASS_USER_ID };
}

Why it's bad: Massive security hole in production

Do this instead:

// GOOD: Environment check
if (
  process.env.ENABLE_AUTH_BYPASS === 'true' &&
  process.env.NODE_ENV !== 'production'
) {
  return { userId: process.env.AUTH_BYPASS_USER_ID };
}

Anti-Pattern 3: Using Bypass for Real User Actions

# BAD: Using bypass to modify production data
curl https://production.com/api/campaigns/delete-all \
  -H "x-dev-auth: dev-bypass"
# This should NEVER work in production!

Why it's bad: Bypasses should only work locally

Troubleshooting Guide

Problem: Auth Bypass Not Working

Symptoms:

  • Endpoint returns 401 Unauthorized
  • Headers seem correct
  • Environment variables set

Diagnosis:

  1. Check if in production (bypass disabled)
  2. Verify header names match exactly
  3. Check token matches AUTH_BYPASS_TOKEN
  4. Look for typos in environment variables

Solution:

# 1. Verify environment
echo $NODE_ENV  # Should be "development" or empty

# 2. Check .env.local
cat .env.local | grep AUTH_BYPASS

# 3. Test with exact headers
curl http://localhost:3000/api/debug/whoami \
  -H "x-dev-auth: dev-bypass" \
  -H "x-dev-user-id: user_2abc123xyz" \
  -v  # Verbose mode to see headers

# 4. Restart dev server (to reload .env.local)

Problem: Can't Test Different Users

Symptoms:

  • Stuck with same user for all requests
  • Want to test multi-user scenarios

Solution: Use test headers (Method 1) instead of environment bypass:

# User 1
curl http://localhost:3000/api/campaigns \
  -H "x-test-user-id: user_1"

# User 2
curl http://localhost:3000/api/campaigns \
  -H "x-test-user-id: user_2"

Related Files

  • /lib/auth/get-auth-or-test.ts - Auth resolver with bypass logic
  • /lib/auth/testable-auth.ts - Test header verification
  • /app/api/debug/whoami/route.ts - Debug endpoint for testing auth
  • /app/api/test/auth-echo/route.ts - Echo auth context

Quick Reference

Headers:

# Test headers (highest priority)
x-test-user-id: user_xxx
x-test-email: test@example.com

# Dev bypass headers
x-dev-auth: dev-bypass
x-dev-user-id: user_xxx  # Optional override
x-dev-email: dev@example.com  # Optional

# Plan bypass (for testing without limits)
x-plan-bypass: all  # or "campaigns" or "creators"

Environment:

# Auth bypass
ENABLE_AUTH_BYPASS=true
AUTH_BYPASS_USER_ID=user_xxx
AUTH_BYPASS_EMAIL=dev@example.com
AUTH_BYPASS_TOKEN=dev-bypass
AUTH_BYPASS_HEADER=x-dev-auth

# Plan bypass
PLAN_VALIDATION_BYPASS=all  # or "campaigns,creators"

Testing Commands:

# Simple GET
curl http://localhost:3000/api/endpoint \
  -H "x-dev-auth: dev-bypass"

# POST with JSON
curl -X POST http://localhost:3000/api/endpoint \
  -H "x-dev-auth: dev-bypass" \
  -H "Content-Type: application/json" \
  -d '{"key":"value"}'

# Different user
curl http://localhost:3000/api/endpoint \
  -H "x-test-user-id: user_different"

# With plan bypass
curl http://localhost:3000/api/endpoint \
  -H "x-dev-auth: dev-bypass" \
  -H "x-plan-bypass: all"

Repository

Sanchay-T
Sanchay-T
Author
Sanchay-T/influencer-platform-app/small-fixes/.claude/skills/test-auth-wrapper
1
Stars
1
Forks
Updated4d ago
Added1w ago