Every protected route in Judicial Backend is guarded by theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/BladimirGS/judicial-backend/llms.txt
Use this file to discover all available pages before exploring further.
protect middleware, defined in src/modules/auth/middlewares/protect.middleware.ts. It accepts only RS256-signed JWTs whose public key is fetched on-demand from the external authentication API’s JWKS endpoint. On success it attaches the decoded payload to req.user and calls next(); on any failure it raises a typed AppError that the global error handler converts into a 401 response.
Verification Flow
Extract Bearer token from the Authorization header
The middleware reads No further processing occurs — the request is rejected before any cryptographic work is attempted.
req.headers.authorization. If the header is absent or does not start with "Bearer " it immediately throws:Decode the JWT header to read the key ID (kid)
jwt.decode(token, { complete: true }) performs a non-verifying decode to extract the JOSE header. The kid field identifies which key in the JWKS set was used to sign the token:kid is missing the token cannot be verified and is rejected as invalid.Fetch the matching public key from the JWKS endpoint
The The JWKS endpoint is
JwksClient (from jwks-rsa) is passed the kid extracted in the previous step. It resolves the correct key object from the remote JWKS document and returns the PEM-encoded public key:${EXTERNAL_AUTH_URL}/api/AuthJWT/GetJwks. The client is initialised once at module load time with caching enabled (see JWKS Caching below).Verify RS256 signature, issuer, and audience
With the public key in hand,
jwt.verify performs full cryptographic verification and claim validation in a single call:jsonwebtoken will throw a TokenExpiredError if the exp claim is in the past, a JsonWebTokenError for any signature or claim mismatch, or a general error for unexpected failures. All three paths are caught and converted to descriptive AppError instances with 401 status codes.The JwtPayload Type
JwtPayload is defined in src/modules/auth/types/auth.types.ts as an open interface that captures the standard JWT registered claims while allowing arbitrary additional claims from the external identity provider:
jwt.verify enforces the critical ones (iss, aud, exp) at runtime via the options object. The index signature ([key: string]: unknown) allows downstream handlers to access provider-specific claims (for example a nombre or roles field) without casting to any.
Express Global Type Augmentation
The sameauth.types.ts file augments the global Express namespace so that req.user is statically typed across the entire codebase:
? makes user optional, which correctly models unauthenticated contexts (for example inside the auth routes themselves).
JWKS Caching
The
JwksClient is configured with cache: true, cacheMaxEntries: 5, and cacheMaxAge: 600_000 (10 minutes). This means the public key for a given kid is fetched from the external API at most once every 10 minutes, regardless of how many requests arrive. The cache significantly reduces latency and eliminates unnecessary network calls to the authentication server on every protected request.createProtectMiddleware(jwksClient) accepts any object that satisfies JwksClientLike, which makes the middleware straightforward to test by injecting a stub client.
Error Responses
| Condition | HTTP Status | Error Code |
|---|---|---|
Authorization header missing or malformed | 401 | UNAUTHORIZED |
JWT header has no kid field | 401 | INVALID_TOKEN |
JWT_ISSUER or JWT_AUDIENCE env vars not set | 500 | CONFIG_ERROR |
| Token signature invalid or claims mismatch | 401 | INVALID_TOKEN |
Token has expired (exp in the past) | 401 | TOKEN_EXPIRED |
| Unexpected error during verification | 401 | VALIDATION_ERROR |
asyncHandler, which forwards them to the global error handler middleware. Clients receive a consistent JSON envelope:
How protect Is Applied in routes/index.ts
Protection is registered once per route group, not per individual endpoint. This is the completesrc/routes/index.ts:
protect middleware is placed after the rate limiter and before the module router, so rate limiting applies to all requests (including bad-token requests) while JWT verification happens before any business logic runs.
Adding Protection to a New Route
To protect a new module, importprotect and apiLimiter in src/routes/index.ts and add a router.use line following the same pattern:
req.user will be available to every handler in newRoutes automatically.