Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/JFKoryy/autopart-pro/llms.txt

Use this file to discover all available pages before exploring further.

AutoPart Pro uses JSON Web Tokens (JWT) for stateless authentication. Every protected endpoint validates the token you supply, extracts your user ID and role from it, and uses that information to enforce access control — without an additional database round-trip on each request. This page explains how to obtain a token, how to attach it to requests, what the token contains, how long it lasts, and how the frontend manages it.

How It Works

The server signs tokens using the HS256 algorithm with a secret stored in the JWT_SECRET environment variable. The decoded payload embedded in every token contains exactly two claims:
{
  "id": 42,
  "role": "admin"
}
  • id — the numeric primary key of the user in the database.
  • role — one of admin, employee, or client, assigned at registration or updated by an admin later.
The protect middleware in authMiddleware.js verifies the signature and injects the decoded payload into req.user so downstream route handlers and role checks can read it directly.

Token Lifetime

Tokens expire 1 hour after they are issued. After expiry the server rejects the token with a 401 response and the client must re-authenticate.
Tokens are not refreshed automatically. If a user’s session is active when their token expires, the next API call will return 401. Your frontend should catch this response, clear the stored token, and redirect the user to the login screen so they can obtain a new token.

Obtaining a Token: Registration and Login Flow

1

Register a new account

Send a POST request to /api/auth/register with name, email, and password in the JSON body. A successful response returns a token immediately — the user is authenticated right away.
curl -X POST http://localhost:5000/api/auth/register \
  -H 'Content-Type: application/json' \
  -d '{"name":"Jane Doe","email":"jane@example.com","password":"secret123"}'
Response 201 Created:
{
  "message": "¡Usuario registrado con éxito! Ya puedes iniciar sesión.",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": 7,
    "name": "Jane Doe",
    "email": "jane@example.com",
    "role": "user"
  }
}
The user.role field in the register response body is always "user". The JWT payload itself encodes client as the default role. An admin can later promote the account to employee or admin using PUT /api/users/:id/role.
2

Log in to an existing account

Send a POST request to /api/auth/login with email and password. The server verifies the bcrypt-hashed password against the database record and, if it matches, returns a fresh token.
curl -X POST http://localhost:5000/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"jane@example.com","password":"secret123"}'
Response 200 OK:
{
  "message": "¡Inicio de sesión exitoso!",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": 7,
    "name": "Jane Doe",
    "email": "jane@example.com",
    "role": "client"
  }
}
Store the token value — you will pass it with every subsequent protected request.
3

Attach the token to protected requests

Include the token as a Bearer credential in the Authorization header of every request that requires authentication.
Authorization: Bearer <token>
Example — fetch low-stock products:
curl -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
  http://localhost:5000/api/products/low-stock
The server extracts the token from the header, verifies the signature, and proceeds with the request if it is valid and unexpired.

Passing the Token

The Authorization header must follow the Bearer scheme exactly. The protect middleware checks that the header is present and starts with the literal string Bearer (including the trailing space) before attempting to verify the token:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDIsInJvbGUiOiJhZG1pbiJ9.SIG
Any deviation from this format — a missing header, a different scheme name, or no space after Bearer — causes the middleware to respond immediately with 401.

Validating a Stored Token

The GET /api/auth/me endpoint lets the frontend confirm that a token stored in localStorage is still valid. It re-fetches the user record from the database using the ID from the token payload and returns the up-to-date user object.
curl -H 'Authorization: Bearer <token>' \
  http://localhost:5000/api/auth/me
Response 200 OK:
{
  "success": true,
  "user": {
    "id": 7,
    "name": "Jane Doe",
    "email": "jane@example.com",
    "role": "client"
  }
}
If the token is expired or the user no longer exists in the database, the server returns 401 or 404 respectively.
Call GET /api/auth/me on application startup to silently restore a user’s session from a stored token. If the call fails, clear the token and show the login screen.

Frontend Usage

The React frontend (frontend/src/services/api.js) stores the JWT in localStorage under the key token and retrieves it via a getAuthHeader() helper that automatically builds the correct headers object for every authenticated fetch call:
function getAuthHeader() {
  const token = localStorage.getItem('token')
  return {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  }
}
This helper is used as the headers option on all authenticated requests, for example:
export async function getLowStockProducts() {
  const response = await fetch(`${import.meta.env.VITE_API_URL}/products/low-stock`, {
    method: 'GET',
    headers: getAuthHeader()
  })
  const data = await response.json()
  if (!response.ok) {
    throw new Error(data.message || 'Error al obtener productos con stock bajo')
  }
  return data.data
}
The validateToken() function in the same file calls GET /api/auth/me, removes the token from localStorage if the server returns a non-OK status, and returns null to signal that re-authentication is needed:
export async function validateToken() {
  const token = localStorage.getItem('token')
  if (!token) return null

  const response = await fetch(`${import.meta.env.VITE_API_URL}/auth/me`, {
    headers: getAuthHeader()
  })

  if (!response.ok) {
    localStorage.removeItem('token')
    return null
  }

  const data = await response.json()
  return data.user
}

Error Reference

Missing or Malformed Token — 401

Returned when the Authorization header is absent or does not start with Bearer .
{
  "message": "No autorizado, no se proporcionó un token."
}

Invalid or Expired Token — 401

Returned when the token fails JWT verification — either the signature is wrong or the token has passed its 1-hour expiry.
{
  "message": "Token no válido o expirado."
}

Insufficient Role — 403

Returned by the authorize role middleware when the authenticated user’s role is not in the list of roles permitted for that endpoint (for example, a client trying to delete a product).
{
  "success": false,
  "message": "Acceso denegado. No se encontraron roles asignados."
}

Role Summary

RoleDescription
adminFull access to all endpoints including user management and product mutations
employeeCan view and interact with inventory and sales, but cannot manage users or delete products
clientCan browse the product catalog, complete checkouts, and view their own sales history

Build docs developers (and LLMs) love