Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nelrondon/backend-proyecto-estructuras/llms.txt

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

The Estructuras Backend API is configured entirely through environment variables loaded from a .env file at the project root via dotenv. There is no separate configuration UI or runtime config endpoint — every setting is resolved at startup from src/config.js and src/db.js. This page documents every variable, the CORS allowlist, the Turso database connection, and the security defaults baked into the server.

Environment Variables

Place these variables in a .env file at the root of the repository (alongside package.json). The server reads them once at startup; a restart is required for changes to take effect.
# .env — full example
PORT=3000
SECRET_KEY=a8f3k9z2m1xq7p4w6n0r5b2v8c3s1t9u
DB_TOKEN=eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...
SALT_ROUNDS=12
SECRET_KEY must be a cryptographically strong random string in any non-development environment. If an attacker learns this value they can forge valid session tokens for any user ID. Generate one with node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" or an equivalent tool.

PORT
number
default:"3000"
The TCP port the Express HTTP server will bind to. Override this when deploying to a host that assigns a dynamic port via the environment (e.g., process.env.PORT on Render or Railway).
PORT=8080
SECRET_KEY
string
required
The secret string used by jsonwebtoken to sign and verify all JWT session tokens. Both createAccessToken and verifyToken in src/libs/jwt.js read this value from src/config.js. If this variable is absent the server will start but JWT signing will fail, breaking all authentication endpoints.
SECRET_KEY=a8f3k9z2m1xq7p4w6n0r5b2v8c3s1t9u
Never reuse a weak or guessable string here. Any compromise of SECRET_KEY invalidates all existing sessions and requires an immediate secret rotation followed by a server restart.
DB_TOKEN
string
required
The Turso authentication token passed to @libsql/client as authToken. The database URL is hardcoded in src/db.js as libsql://estructuradb-nelrondon.aws-us-east-1.turso.io. If this token is missing or invalid, every database query will throw an authentication error.
DB_TOKEN=eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...
See Database Setup below for instructions on obtaining this token.
SALT_ROUNDS
number
default:"10"
The bcrypt cost factor used when hashing user passwords. Higher values increase security but also increase the CPU time spent on each registration or login. A value of 10 is the bcrypt default and is appropriate for most deployments; increase to 12 or 14 on hardware that can absorb the extra cost.
SALT_ROUNDS=12
This value is read by the UserModel at runtime. Changing it only affects new passwords — existing password hashes in the database are unaffected because bcrypt stores the cost factor inside the hash string itself.

Database Setup

Estructuras uses Turso — a globally distributed SQLite-compatible database built on libSQL — as its persistence layer. The connection is established in src/db.js:
// src/db.js
import { createClient } from "@libsql/client";
import dotenv from "dotenv";
dotenv.config();

export const db = createClient({
  url: "libsql://estructuradb-nelrondon.aws-us-east-1.turso.io",
  authToken: process.env.DB_TOKEN,
});
The database URL is fixed to the project’s Turso instance. If you are running a fork or want to point the API at your own database, change the url value in src/db.js to your own Turso database URL and supply the corresponding token in DB_TOKEN.

Obtaining a Turso Auth Token

  1. Install the Turso CLI: curl -sSfL https://get.tur.so/install.sh | bash
  2. Log in: turso auth login
  3. Create a token for your database:
    turso db tokens create estructuradb-nelrondon
    
  4. Copy the printed JWT string and set it as DB_TOKEN in your .env.
Turso tokens can be scoped to read-only or full access. For production deployments where the API needs to write data, generate a full-access token. For a read-only replica or analytics instance, generate a --read-only token.

CORS Allowed Origins

The server enforces a static origin allowlist defined in src/config.js. Requests from any origin not on this list are rejected with a CORS error before reaching any route handler.
// src/config.js
export const ALLOWED_ORIGINS = [
  "http://localhost:5173",                              // Local Vite dev server
  "https://proyecto-estructuras-topaz.vercel.app",     // Production frontend (Vercel)
];
The CORS middleware in src/index.js also passes through requests with no Origin header (e.g., server-to-server calls, curl without an Origin flag, and Postman by default):
// src/index.js
app.use(
  cors({
    origin: function (origin, callback) {
      if (!origin) return callback(null, true);        // Allow non-browser clients
      if (ALLOWED_ORIGINS.includes(origin)) {
        return callback(null, true);
      } else {
        return callback(new Error("Not allowed by CORS"));
      }
    },
    credentials: true,     // Required to pass cookies cross-origin
  })
);

Adding a New Allowed Origin

To permit an additional frontend (for example, a staging deployment at https://staging.myapp.com), open src/config.js and append the origin to the array:
export const ALLOWED_ORIGINS = [
  "http://localhost:5173",
  "https://proyecto-estructuras-topaz.vercel.app",
  "https://staging.myapp.com",   // ← add your origin here
];
Restart the server after saving the file. The --watch flag used in pnpm start will detect the change and restart automatically.
Never add a wildcard (*) to ALLOWED_ORIGINS. The CORS middleware is configured with credentials: true, which requires explicit origins — browsers will block credentialed requests to a wildcard origin regardless.

Security Settings

The following security behaviors are hardcoded in src/index.js and src/controllers/auth.controller.js. They are not configurable through environment variables but are documented here for reference.

Disabled X-Powered-By Header

app.disable("x-powered-by");
Express normally adds an X-Powered-By: Express response header that reveals the server framework to anyone who inspects the response. This is disabled globally to reduce information leakage. Every session token is issued with the following cookie attributes:
res.cookie("token", token, {
  httpOnly: true,          // Inaccessible to JavaScript (prevents XSS token theft)
  secure: true,            // Only transmitted over HTTPS connections
  sameSite: "none",        // Required for cross-site cookie sharing (frontend on a different domain)
  maxAge: 7 * 24 * 60 * 60 * 1000,  // 7 days in milliseconds
});
AttributeValueEffect
httpOnlytrueThe cookie cannot be read by document.cookie or any JavaScript — it is managed entirely by the browser
securetrueThe cookie is only sent over HTTPS; it will not be sent over plain HTTP
sameSite"none"Allows the cookie to be sent on cross-site requests, which is necessary when the frontend is on a different domain (e.g., Vercel) than the API
maxAge604800000 msThe cookie and the JWT inside it both expire after exactly 7 days
Because secure: true is set unconditionally, the authentication cookie will not be sent by browsers over http:// — including http://localhost. When developing locally with a browser-based frontend, either serve the frontend and API over HTTPS (e.g., using mkcert) or temporarily adjust the cookie options in src/controllers/auth.controller.js for local development only.

JWT Expiry

Tokens are signed with expiresIn: "7d" in src/libs/jwt.js. After 7 days the token’s exp claim will be in the past and jwt.verify will throw a TokenExpiredError, causing protected endpoints to return 401 Unauthorized. The user must log in again to receive a new token.

Full .env Reference

# ─────────────────────────────────────────────
# Estructuras Backend API — Environment Variables
# ─────────────────────────────────────────────

# TCP port for the Express server (default: 3000)
PORT=3000

# JWT signing secret — use a strong random value in production
# Generate: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
SECRET_KEY=replace-this-with-a-strong-random-secret

# Turso database authentication token
# Obtain with: turso db tokens create estructuradb-nelrondon
DB_TOKEN=eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...

# bcrypt salt rounds for password hashing (default: 10)
SALT_ROUNDS=10

Build docs developers (and LLMs) love