Skip to main content

Overview

The Los Inmaduros Backend API uses Clerk for authentication. All protected endpoints require a valid JWT token in the Authorization header.

Authentication Flow

  1. User signs in through your frontend application using Clerk
  2. Clerk generates a JWT token for the authenticated session
  3. Include the token in the Authorization header for API requests
  4. Backend verifies the token and syncs user data to the database

Making Authenticated Requests

Include the JWT token in the Authorization header with the Bearer scheme:
curl -X GET https://api.losinmaduros.com/api/reviews/my-reviews \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
fetch('https://api.losinmaduros.com/api/reviews/my-reviews', {
  headers: {
    'Authorization': `Bearer ${clerkToken}`,
    'Content-Type': 'application/json'
  }
});

Authentication Middleware

The API implements three authentication middleware functions:

requireAuth

Protects endpoints that require authentication. Verifies the JWT token and adds user information to the request:
req.auth = {
  userId: string;      // Database user ID
  clerkId: string;     // Clerk user ID
  role: string;        // User role (USER or ADMIN)
}
Location: /home/daytona/workspace/source/src/shared/middlewares/auth.middleware.ts:27

requireAdmin

Restricts access to admin users only. Must be used after requireAuth:
// Example: Admin-only route
router.delete('/api/reviews/:id', requireAuth, requireAdmin, controller.delete);
Location: /home/daytona/workspace/source/src/shared/middlewares/auth.middleware.ts:77

optionalAuth

Adds authentication data if a token is provided, but doesn’t require it. Useful for endpoints that return different data for authenticated vs. anonymous users:
// Example: Public endpoint with optional auth
router.get('/api/routes/:slug', optionalAuth, controller.getRoute);
Location: /home/daytona/workspace/source/src/shared/middlewares/auth.middleware.ts:97

Protected vs Public Endpoints

Protected Endpoints (Require Authentication)

  • POST /api/routes/:routeId/reviews - Create review
  • PUT /api/reviews/:reviewId - Update review
  • DELETE /api/reviews/:reviewId - Delete review
  • GET /api/reviews/my-reviews - Get user’s reviews
  • POST /api/favorites - Add to favorites
  • DELETE /api/favorites/:id - Remove from favorites
  • All attendance and route call endpoints

Public Endpoints

  • GET /api/routes - List all routes
  • GET /api/routes/:slug - Get route details
  • GET /api/routes/:routeId/reviews - Get route reviews
  • GET /api/config - Get app configuration

Error Responses

When authentication fails, the API returns a 401 Unauthorized response:
{
  "success": false,
  "error": "No authentication token provided"
}
{
  "success": false,
  "error": "Invalid authentication token"
}
{
  "success": false,
  "error": "Admin access required"
}

Development Testing

In development mode, you can generate test tokens using the /api/auth/test-token endpoint:
curl -X POST http://localhost:8000/api/auth/test-token \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]"}'
Response:
{
  "success": true,
  "message": "Test token generated successfully",
  "data": {
    "userId": "clk1234567890",
    "email": "[email protected]",
    "sessionId": "sess_1234567890",
    "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "warning": "This endpoint should be removed in production",
    "instructions": "Copy this token and use it in Postman: Authorization: Bearer <token>"
  }
}
The /api/auth/test-token endpoint is only available in development and returns a 404 in production.

User Synchronization

When a user authenticates for the first time, the backend automatically:
  1. Verifies the JWT token with Clerk
  2. Extracts the Clerk user ID (clerkId)
  3. Creates a user record in the database if it doesn’t exist
  4. Returns the database user ID and role for subsequent operations
This ensures all authenticated users have a corresponding record in the application database.

Build docs developers (and LLMs) love