The Agencia de Habilidades para el Futuro API uses theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Manuelfg1985/Proyecto_Final_26/llms.txt
Use this file to discover all available pages before exploring further.
jsonwebtoken library to sign tokens at login and verify them on every protected request. The signing secret is read from the JWT_SECRET environment variable at runtime — it is never hardcoded. Token generation happens in controllers/auth.js and token verification is handled by the reusable authMiddleware in middlewares/authMiddleware.js.
Token generation
When a client posts credentials toPOST /api/auth/login, the login controller in controllers/auth.js performs three steps:
- Validates that both
emailandpasswordfields are present in the request body. - Compares the submitted values directly against the
ADMIN_EMAILandADMIN_PASSWORDenvironment variables. There is no database lookup — this is a single-admin model. - Signs a JWT with the payload
{ email }and returns it to the client if the credentials match.
JWT_SECRET and expires after 1 hour (expiresIn: '1h').
The JWT payload contains only the
email field. No role, ID, or additional claims are embedded in the token. The decoded payload is later available as req.user inside protected route handlers.Auth middleware
TheauthMiddleware function in middlewares/authMiddleware.js is applied as route-level middleware on every protected endpoint. It runs before the route handler and either allows the request through or rejects it immediately.
The middleware does the following in order:
- Reads the
Authorizationheader from the incoming request. - Checks that the header exists and starts with
'Bearer '. If not, it returns401. - Splits the header on the space character and extracts the raw token string.
- Calls
jwt.verify(token, process.env.JWT_SECRET)to validate the signature and check expiry. - Attaches the decoded payload to
req.userso downstream handlers can access it. - Calls
next()to pass control to the route handler. - If
jwt.verify()throws for any reason (bad signature, expired token, malformed string), it catches the error and returns403.
Error responses
The following error responses can be returned by the login endpoint or the auth middleware:| HTTP status | Message | Cause |
|---|---|---|
400 Bad Request | Email y contraseña son requeridos | The request body is missing email, password, or both. |
401 Unauthorized | Credenciales inválidas | The submitted email or password does not match the environment variable values. |
401 Unauthorized | Acceso denegado. No se proporcionó un token válido. | The Authorization header is absent or does not start with Bearer . |
403 Forbidden | Token inválido o expirado | The token signature is invalid, the token has expired, or the token string is malformed. |
500 Internal Server Error | Error en el servidor | An unexpected error occurred during the login process. |
Example: obtaining a token
Send aPOST request to /api/auth/login with the admin credentials as a JSON body.
200 OK):
token from the response. This is the Bearer token you will include in all subsequent protected requests.
Example: using a token
Pass the token in theAuthorization header with the Bearer prefix. The following example calls the protected GET /api/auth/private endpoint, which echoes back the decoded req.user payload.
200 OK):
data field contains the decoded JWT payload — the email claim that was embedded at signing time, along with the standard iat (issued at) and exp (expiry) timestamps added automatically by jsonwebtoken.
The same
Authorization: Bearer <token> header format applies to every protected route: POST /api/postulantes, PUT /api/postulantes/:id, and DELETE /api/postulantes/:id. See the Authentication Overview for the full list of protected vs public routes.