Authentication API

Complete reference for user authentication endpoints using Supabase Auth with JWT token management.

๐Ÿ” Authentication Methods

The API supports two authentication methods:

  1. Supabase Auth - Primary authentication system
  2. Legacy Admin Tokens - Backward compatibility for admin endpoints

๐Ÿ“ก Endpoints

Sign Up

Register a new user account.

Endpoint: POST /api/auth/signup

Request Body:

{
  "email": "user@example.com",
  "password": "securepassword123",
  "name": "John Doe"
}

Validation:

  • email: Valid email format (required)
  • password: Minimum 6 characters (required)
  • name: Minimum 2 characters (required)

Response: 201 Created

{
  "success": true,
  "data": {
    "user": {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "email": "user@example.com",
      "name": "John Doe",
      "createdAt": "2025-12-18T10:00:00.000Z"
    },
    "session": {
      "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refreshToken": "v1.MJBbF...",
      "expiresIn": 3600,
      "tokenType": "bearer"
    }
  },
  "message": "User registered successfully"
}

Error Responses:

// 400 Bad Request - Validation Error
{
  "success": false,
  "error": "Validation failed",
  "details": {
    "email": ["Invalid email format"],
    "password": ["Password must be at least 6 characters"]
  }
}

// 409 Conflict - User Already Exists
{
  "success": false,
  "error": "User with this email already exists"
}

// 500 Internal Server Error
{
  "success": false,
  "error": "Failed to register user"
}

Example:

curl -X POST http://localhost:3001/api/auth/signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "password": "mypassword123",
    "name": "John Doe"
  }'

Sign In

Authenticate with email and password.

Endpoint: POST /api/auth/signin

Request Body:

{
  "email": "user@example.com",
  "password": "securepassword123"
}

Response: 200 OK

{
  "success": true,
  "data": {
    "user": {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "email": "user@example.com",
      "name": "John Doe",
      "lastLogin": "2025-12-18T10:00:00.000Z"
    },
    "session": {
      "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refreshToken": "v1.MJBbF...",
      "expiresIn": 3600,
      "tokenType": "bearer"
    }
  },
  "message": "Signed in successfully"
}

Error Responses:

// 401 Unauthorized - Invalid Credentials
{
  "success": false,
  "error": "Invalid email or password"
}

// 400 Bad Request
{
  "success": false,
  "error": "Email and password are required"
}

Example:

curl -X POST http://localhost:3001/api/auth/signin \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "password": "mypassword123"
  }'

Sign Out

End the current user session.

Endpoint: POST /api/auth/signout

Headers:

Authorization: Bearer <access_token>

Response: 200 OK

{
  "success": true,
  "message": "Signed out successfully"
}

Error Responses:

// 401 Unauthorized
{
  "success": false,
  "error": "No active session"
}

Example:

curl -X POST http://localhost:3001/api/auth/signout \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Reset Password

Request a password reset email.

Endpoint: POST /api/auth/reset-password

Request Body:

{
  "email": "user@example.com"
}

Response: 200 OK

{
  "success": true,
  "message": "Password reset email sent. Check your inbox."
}

Error Responses:

// 400 Bad Request
{
  "success": false,
  "error": "Email is required"
}

// 404 Not Found
{
  "success": false,
  "error": "No user found with this email"
}

Example:

curl -X POST http://localhost:3001/api/auth/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com"
  }'

Update Password

Update password using reset token.

Endpoint: POST /api/auth/update-password

Request Body:

{
  "token": "reset_token_from_email",
  "newPassword": "newsecurepassword456"
}

Response: 200 OK

{
  "success": true,
  "message": "Password updated successfully"
}

Error Responses:

// 400 Bad Request - Invalid Token
{
  "success": false,
  "error": "Invalid or expired reset token"
}

// 400 Bad Request - Weak Password
{
  "success": false,
  "error": "Password must be at least 6 characters"
}

Example:

curl -X POST http://localhost:3001/api/auth/update-password \
  -H "Content-Type: application/json" \
  -d '{
    "token": "abc123...",
    "newPassword": "newpassword123"
  }'

Get Current User

Retrieve authenticated user's profile.

Endpoint: GET /api/auth/me

Headers:

Authorization: Bearer <access_token>

Response: 200 OK

{
  "success": true,
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "email": "user@example.com",
    "name": "John Doe",
    "createdAt": "2025-12-01T10:00:00.000Z",
    "lastLogin": "2025-12-18T10:00:00.000Z",
    "roles": ["user"]
  }
}

Error Responses:

// 401 Unauthorized
{
  "success": false,
  "error": "Authentication required"
}

Example:

curl http://localhost:3001/api/auth/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Link social authentication providers.

Endpoint: POST /api/auth/link

Headers:

Authorization: Bearer <access_token>

Request Body:

{
  "provider": "google",
  "token": "google_oauth_token"
}

Response: 200 OK

{
  "success": true,
  "message": "Account linked successfully"
}

๐Ÿ”‘ JWT Token Usage

Access Tokens

Purpose: Authenticate API requests
Lifetime: 1 hour (3600 seconds)
Storage: Client-side (memory or secure storage)

Refresh Tokens

Purpose: Obtain new access tokens
Lifetime: 30 days
Storage: HttpOnly cookie (recommended)

Token Refresh Flow

sequenceDiagram
    participant Client
    participant API
    participant Supabase

    Client->>API: Request with expired access token
    API-->>Client: 401 Unauthorized

    Client->>API: POST /api/auth/refresh (with refresh token)
    API->>Supabase: Validate refresh token
    Supabase-->>API: New access token
    API-->>Client: New session tokens

    Client->>API: Retry request with new access token
    API-->>Client: Success response

Using Tokens in Requests

Header Format:

Authorization: Bearer <access_token>

Example with curl:

curl http://localhost:3001/api/users/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Example with JavaScript:

const response = await fetch('http://localhost:3001/api/users/me', {
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json',
  },
});

๐Ÿ›ก๏ธ Security Best Practices

Password Requirements

  • Minimum 6 characters
  • Mix of uppercase, lowercase, numbers (recommended)
  • No common passwords
  • No personal information

Token Security

  1. Never expose tokens in URLs
  2. Store access tokens securely (memory or secure storage)
  3. Use HttpOnly cookies for refresh tokens
  4. Implement token rotation
  5. Clear tokens on logout

Rate Limiting

Authentication endpoints are rate limited:

  • 10 requests per minute per IP for signup/signin
  • 5 requests per minute per IP for password reset
  • Prevents brute force attacks

๐Ÿ” Admin Authentication (Legacy)

For backward compatibility, admin endpoints accept legacy JWT tokens.

Generating Admin Token

import jwt from 'jsonwebtoken';

const token = jwt.sign(
  { admin: true, userId: 'admin-id' },
  process.env.ADMIN_TOKEN_SECRET,
  { expiresIn: '24h' }
);

Using Admin Token

curl http://localhost:3001/api/get-feedback \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

๐Ÿงช Testing Authentication

Postman Collection

{
  "info": {
    "name": "Auth API Tests"
  },
  "item": [
    {
      "name": "Sign Up",
      "request": {
        "method": "POST",
        "url": "{{base_url}}/api/auth/signup",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"email\": \"test@example.com\",\n  \"password\": \"test123\",\n  \"name\": \"Test User\"\n}"
        }
      }
    }
  ]
}

Unit Test Example

describe('POST /api/auth/signup', () => {
  it('creates a new user successfully', async () => {
    const response = await request(app)
      .post('/api/auth/signup')
      .send({
        email: 'test@example.com',
        password: 'securepass123',
        name: 'Test User',
      });

    expect(response.status).toBe(201);
    expect(response.body.success).toBe(true);
    expect(response.body.data.user.email).toBe('test@example.com');
    expect(response.body.data.session.accessToken).toBeDefined();
  });
});

On this page