Documentation Index
Fetch the complete documentation index at: https://mintlify.com/fredy-rizo/despacho-backend/llms.txt
Use this file to discover all available pages before exploring further.
Despacho Backend secures its lawyer-facing endpoints with JSON Web Tokens (JWT). When a lawyer account is created, the password is hashed and stored safely in MongoDB. On every subsequent login, the server verifies the credentials and issues a signed JWT that the client must include in every protected request. Tokens are valid for 365 days, so lawyers stay authenticated across long work sessions without needing to re-login frequently.
How authentication works
Registration
Sending a POST request to /api/lawyer/user/create with email and password in the request body triggers the following sequence:
- The server checks that both fields are present; missing fields return
403.
- The email is checked for uniqueness — duplicate emails return
203.
- The password is hashed with bcrypt at cost factor 10 via
encryptPassword().
- A new
LawyerUser document is saved to MongoDB with the default role [{ name: "Admin", value: "1" }].
// From lawyerUserController.js — registration handler
const pass = await encryptPassword(password);
const data_lawyer_user = new LawyerUser({
email,
password: pass,
role: [{ name: "Admin", value: "1" }],
});
const new_user = await data_lawyer_user.save();
Login
Sending a POST request to /api/lawyer/user/login with email and password triggers:
- The server looks up the
LawyerUser document by email (case-insensitive via .toLowerCase()).
- The submitted password is compared against the stored bcrypt hash via
comparePassword().
- On success,
jwt.sign() creates a token with the payload { _id, email, role }, signed with the SECRET environment variable, and set to expire in 365 days.
- The new token is persisted back to the
LawyerUser document and returned in the response body.
// From lawyerUserController.js — login handler
const token = jwt.sign(
{
_id: userX._id,
email: userX.email,
role: userX.role,
},
config.SECRET,
{
expiresIn: "365d",
}
);
JWT structure
A decoded token carries the following payload:
{
"_id": "64a1f2c3e4b0d5f6a7b8c9d0",
"email": "lawyer@despacho.com",
"role": [
{ "name": "Admin", "value": "1" }
],
"iat": 1700000000,
"exp": 1731536000
}
| Field | Type | Description |
|---|
_id | string | MongoDB ObjectId of the LawyerUser document |
email | string | The lawyer’s registered email address |
role | array | Array of role objects { name, value } (see Roles) |
iat | number | Unix timestamp — when the token was issued |
exp | number | Unix timestamp — when the token expires (iat + 365d) |
Tokens expire after 365 days. Once a token expires, the Token middleware returns 403 with { msj: "Sesion finalizada", status: false }. The lawyer must call POST /api/lawyer/user/login again to obtain a fresh token.
Using the token
Every protected endpoint expects the token in the Authorization HTTP header using the Bearer scheme:
Authorization: Bearer <your_jwt_token>
curl example — login and use the token
# Step 1: Login and capture the token
curl -s -X POST https://api.despacho.example.com/api/lawyer/user/login \
-H "Content-Type: application/json" \
-d '{"email": "lawyer@despacho.com", "password": "mySecurePass"}' \
| jq -r '.token'
# Step 2: Use the token to list pending reservations
curl -X POST https://api.despacho.example.com/api/form/reserve/list/reservation-false \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json"
Store the JWT securely on the client side. Do not persist it in localStorage in web browsers — use an HttpOnly cookie or a secure in-memory store to reduce exposure to XSS attacks. Never log or expose the raw token in client-side error reports.
Token middleware (Token)
The Token middleware in src/middleware/tools/segurity.js guards every lawyer-only route. It runs before the route handler and either calls next() to proceed or short-circuits the request with an error response.
What it does, step by step:
- Reads the
authorization header from the incoming request.
- Splits the header value on a space character and takes index
[1] to isolate the raw token (stripping the Bearer prefix).
- If no token is found, responds immediately with
401 Unauthorized.
- Calls
jwt.verify(token, config.SECRET, callback) to validate the signature and expiry.
- On a valid token, queries MongoDB for the
LawyerUser document using the _id from the decoded payload. If no matching user is found, responds with 404 Not Found.
- Attaches
{ _id, email, role } to req.user and calls next().
// src/middleware/tools/segurity.js
import jwt from "jsonwebtoken";
import config from "../../config.js";
import { LawyerUser } from "../../models/LawyerUser.js";
export const Token = (req, res, next) => {
const authHeader = req.headers["authorization"];
const token = authHeader?.split(" ")[1];
if (!token)
return res.status(401).json({ msj: "Sin autorizacion", status: false });
jwt.verify(token, config.SECRET, async (err, user) => {
if (err) {
if (err.message === "jwt expired")
return res
.status(403)
.json({ msj: "Sesion finalizada", status: false });
return res
.status(403)
.json({ msj: `${err.message}. Rechazo en la conexion`, status: false });
}
let lawyer_userX = await LawyerUser.findById(user._id);
if (!lawyer_userX)
return res
.status(404)
.json({ msj: "Usuario no encontrado", status: false });
req.user = {
_id: lawyer_userX._id,
email: lawyer_userX.email,
role: lawyer_userX.role,
};
next();
return;
});
};
Protected endpoints
The following reservation management endpoints require the Token middleware — any request without a valid bearer token will be rejected:
| Endpoint | Middleware |
|---|
POST /api/form/reserve/accept/:reserveId/reserve | Token |
POST /api/form/reserve/list/reservation-true | Token, Paginate |
POST /api/form/reserve/list/reservation-false | Token, Paginate |
POST /api/form/reserve/list/reservation-all | Token, Paginate |
POST /api/form/reserve/remove/reservation/:reservationId | Token |
Error responses
| Scenario | Status | Response body |
|---|
No Authorization header / no token | 401 | { "msj": "Sin autorizacion", "status": false } |
| Token expired | 403 | { "msj": "Sesion finalizada", "status": false } |
| Token signature invalid or malformed | 403 | { "msj": "<error>. Rechazo en la conexion", "status": false } |
| Token valid but user deleted from DB | 404 | { "msj": "Usuario no encontrado", "status": false } |
Roles
The role field on a LawyerUser document is an array of role objects, where each object has a name (human-readable label) and a value (numeric string identifier). This structure allows a single user to hold multiple roles simultaneously.
"role": [
{ "name": "Admin", "value": "1" }
]
| Role name | value | Description |
|---|
Admin | "1" | Standard lawyer/administrator account. Assigned automatically on registration. |
SuperAdmin | "2" | Elevated privileges for managing the system. Must be assigned manually. |
The role array is embedded directly in the JWT payload, making it available to any downstream middleware or controller via req.user.role without an additional database round-trip.