Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/fredy-rizo/ecommerce-delivery/llms.txt

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

The Ecommerce Delivery API enforces access control through a combination of JSON Web Tokens and role-based middleware guards. Every user carries a roles array in their profile, and four middleware functions — Token, TokenAdmin, TokenCompany, and TokenOptional — cooperate to decide whether a request is allowed to proceed to its handler.

The five roles

Roles are defined as {name, value} objects stored on the User document. The numeric string in the value field is what the middleware checks programmatically.
ValueNameDescription
"1"usuarioRegular buyer — can place orders and upload payment proof
"2"adminAdministrator — can validate payments, change order statuses, and search all sales
"3"promotorPromotor — promotional role
"4"invitadoGuest — limited access role
"5"companyCompany — can list and export all sales records
The roles field on the User model is an array of {name, value} objects, not a single scalar. This means a single user account can hold more than one role simultaneously — for example, a user with both "2" (admin) and "5" (company) values would pass both the TokenAdmin and TokenCompany guards without needing separate accounts.

The four middleware guards

All four guards live in src/middleware/libs/segurity.js and are applied directly in the route definitions.

Token — authentication baseline

Token is the foundation of all protected routes. It:
  1. Reads the Authorization: Bearer <token> header.
  2. Verifies the JWT signature against the server secret.
  3. Fetches the corresponding User document from MongoDB.
  4. Attaches a sanitised user object to req.user and calls next().
If no token is present, the response is 401 Unauthorized. If the token is invalid or expired, the response is 403 Forbidden.
// Fields attached to req.user by the Token middleware
req.user = {
  id,
  name,
  address,
  phone_number,
  typeIdentification,
  identification,
  email,
  roles,       // Array of { name, value }
  status,
  membership,
};

TokenAdmin — admin-only gate

TokenAdmin must be chained after Token — it relies on req.user.id already being set. It queries the database once more for the user and checks whether any entry in roles carries value === "2". If not, it returns 403 Forbidden with the message "No tienes permisos para realizar esta accion".

TokenCompany — company-only gate

TokenCompany must be chained after Token — it also relies on req.user.id already being set. It queries the database for the user and checks whether any entry in roles carries value == "5". If no company role is found, it returns 403 Forbidden with the message "No tienes permisos para realizar esta accion".
// How TokenCompany checks for the company role
const rol = userX.roles.find((element) => element.value == "5");
if (rol) return next();

TokenOptional — unauthenticated pass-through

TokenOptional never blocks a request. When no Authorization header is present it simply sets req.user = null and calls next(). When a valid token is provided it populates req.user identically to Token. This guard is used on endpoints — such as product listings — where authenticated users may receive personalised data but anonymous visitors must still be served.

Route-level guard mapping

The table below shows how the guards are applied across the API’s main route groups.
RouteGuards appliedWho can call it
POST /api/sale/pay/:productIdTokenAny authenticated user
POST /api/sale/laod-proof/:saleIdTokenAuthenticated owner or admin
POST /api/sale/status-change/:saleIdTokenAuthenticated user (admin in practice)
POST /api/sale/status-delivery/:saleIdTokenAuthenticated user
POST /api/sale/all-list/:pag?/:perpage?TokenAuthenticated user
POST /api/sale/list-sale/:pag?/:perpage?TokenAuthenticated user
POST /api/sale/export-list-sale-xlsxTokenAuthenticated user
POST /api/sale/get-search/:query/:pag?TokenTokenAdminAdmin only
POST /api/notification/register-token(none)Public
POST /api/user/create(none)Public
POST /api/user/verify-account(none)Public
POST /api/user/resend-code(none)Public
POST /api/user/login(none)Public
POST /api/user/updateTokenAny authenticated user
POST /api/user/recover-password-code(none)Public
POST /api/user/update-password-widthout-token(none)Public
POST /api/user/update-password-width-tokenTokenAny authenticated user
POST /api/user/update-role/:userIdTokenTokenAdminAdmin only
POST /api/user/list-members/:pag?/:perpage?TokenAny authenticated user
POST /api/product/createTokenAny authenticated user
POST /api/product/update/:productIdTokenTokenAdminAdmin only
POST /api/product/delete/:productIdTokenTokenAdminAdmin only
POST /api/product/list-product/:pag?/:perpage?TokenOptionalPublic or authenticated
POST /api/product/pointsTokenAny authenticated user
POST /api/product/list-id/:productIdTokenAny authenticated user
POST /api/product/search-product/:query/:pag?TokenOptionalPublic or authenticated
POST /api/product/get/by-shirt-types/:typeShirtTokenOptionalPublic or authenticated

Updating a user’s roles

Roles are managed by administrators via the user management endpoint:
POST /api/user/update-role/:userId
Authorization: Bearer <admin_jwt>
Content-Type: application/json
{
  "roles": [
    { "name": "admin",   "value": "2" },
    { "name": "company", "value": "5" }
  ]
}

Inspecting roles from the JWT payload

When you decode the JWT on the client side you can inspect the roles to decide which UI elements to render. The decoded payload includes the MongoDB _id; the full roles array is only available after the server hydrates it from the database and attaches it to req.user.
import jwt from "jsonwebtoken";

// Client-side: decode without verification to read claims
const decoded = jwt.decode(token);
console.log(decoded._id); // MongoDB ObjectId string

// Server-side (inside a middleware or controller): roles are on req.user
const isAdmin = req.user.roles.some((r) => r.value === "2");
const isCompany = req.user.roles.some((r) => r.value === "5");

if (isAdmin) {
  // grant admin access
}
Always verify the JWT on the server using jwt.verify() — never trust the decoded payload from the client directly. The Token middleware handles this for every protected route automatically.

Build docs developers (and LLMs) love