ExisJS

exisjs/middleware

The exisjs/middleware module provides the built-in HTTP middleware pipeline for ExisJS. It includes traffic controls, multipart upload handlers, security header suites, and request context enhancers.


Module Exports

import {  // Core & Security  cors,  helmet,  csrf,  hpp,  mongoSanitize,  blockSuspiciousProbes,  timingSafeEqual,  timeout,  routeTimeout,
  // Traffic & Reliability  rateLimit,  idempotent,  dedupe,  ipFilter,  backpressure,  compression,
  // Multipart File Uploads  fileUpload,  fromExpress,
  // Utilities & Observability  requestId,  requestLogger,  serveStatic,  validate,  conditionalGet,} from 'exisjs/middleware'
import type {  CorsConfig,  RateLimitOptions,  IdempotencyOptions,  IpFilterOptions,  FileUploadOptions,  FileUploadLimits,  UploadedFile,  BlockProbesOptions,  TimeoutOptions,  CompressionOptions,} from 'exisjs/middleware'

1. Security & Header Middlewares

helmet(options?)

Sets standard HTTP response headers for protection against XSS, clickjacking, MIME sniffing, and protocol downgrades.

function helmet(options?: HelmetOptions): Handler
OptionTypeDefaultDescription
contentSecurityPolicyboolean | objectfalseConfigures Content Security Policy (Content-Security-Policy).
xFrameOptions'DENY' | 'SAMEORIGIN''SAMEORIGIN'Protects against clickjacking.
hstsboolean | HstsOptionstrue (in prod)Strict Transport Security configuration.
noSniffbooleantrueSets X-Content-Type-Options: nosniff.
xssFilterbooleantrueSets X-XSS-Protection: 0, disabling the legacy browser XSS auditor (current OWASP guidance).

cors(config?)

Manages Cross-Origin Resource Sharing headers, preflight OPTIONS responses, and allowed credentials.

function cors(config?: CorsConfig): Handler
OptionTypeDefaultDescription
originstring | RegExp | string[] | boolean | CorsOriginFn'*'Allowed origin(s) or dynamic resolver function.
methodsstring[]['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD']Allowed HTTP methods.
allowedHeadersstring[]['Content-Type', 'Authorization', 'Accept', 'Origin', ...]Allowed request headers.
exposedHeadersstring[][]Headers exposed to client scripts.
credentialsbooleanfalseSets Access-Control-Allow-Credentials: true.
maxAgenumber86400Preflight cache lifetime in seconds.

csrf(options?)

Enforces Cross-Site Request Forgery protection using the Signed Double-Submit Cookie pattern.

function csrf(options?: CsrfOptions): Handler

blockSuspiciousProbes(options?)

Detects and drops malicious vulnerability scanners probing for sensitive assets (.env, .git, wp-login.php) before they hit route logic or flood log streams.

function blockSuspiciousProbes(options?: BlockProbesOptions): Handler

hpp(options?)

Protects against HTTP Parameter Pollution by normalizing repeated query parameters.

function hpp(options?: HppOptions): Handler

mongoSanitize(options?)

Strips $ and . prefixes from request parameters and body fields to mitigate NoSQL injection vectors.

function mongoSanitize(options?: MongoSanitizeOptions): Handler

2. Traffic, Rate Limiting & Reliability

rateLimit(options?)

In-memory fixed-window rate limiter; expired windows are swept automatically.

function rateLimit(options?: RateLimitOptions): Handler
OptionTypeDefaultDescription
windowMsnumber60000 (1 min)Time window in milliseconds.
maxnumber100Maximum allowed requests within the time window.
keyGenerator(req: Request) => stringreq => req.ipCustom partition key generator.
messagestring | object'Too many requests'Response payload on rate limit breach.
statusCodenumber429HTTP status code for throttled requests.

timeout(options?) & routeTimeout(msOrOptions)

Terminates long-running requests that exceed the specified threshold, returning 503 Service Unavailable.

function timeout(options?: TimeoutOptions): Handlerfunction routeTimeout(msOrOptions: number | TimeoutOptions): Handler
OptionTypeDefaultDescription
msnumber60000Timeout threshold in milliseconds.
statusCodenumber503Response status code upon timeout.
messagestring'Service Unavailable'Error message sent to client.
exclude(string | RegExp)[][]Path patterns exempt from timeout rules.

idempotent(options?)

Caches responses against the Idempotency-Key HTTP header in a bounded in-memory cache (10,000 entries) to prevent duplicate mutations.

function idempotent(options?: IdempotencyOptions): Handler
OptionTypeDefaultDescription
ttlMsnumber86400000 (24h)Cache entry time-to-live in milliseconds.
headerstring'idempotency-key'Target HTTP request header name.

dedupe(options?)

Prevents identical concurrent in-flight requests from being computed more than once simultaneously.

function dedupe(options?: DedupeOptions): Handler

ipFilter(options)

Applies CIDR-compatible IP allow-lists or deny-lists to restrict access to trusted networks.

function ipFilter(options: IpFilterOptions): Handler
OptionTypeDescription
allowstring[]Array of permitted IP addresses or CIDR blocks (e.g. ['10.0.0.0/8', '192.168.1.5']).
denystring[]Array of blocked IP addresses or CIDR blocks.

The address checked is req.ip. Behind a proxy or load balancer, set trustProxy in exis.config.ts so req.ip is the real client; ipFilter never reads X-Forwarded-For itself, because a client can send any value in that header.


backpressure(options?)

Monitors Node.js Event Loop lag in real-time, returning 503 when lag exceeds safe thresholds.

function backpressure(options?: BackpressureOptions): Handler

compression(options?)

Applies Gzip, Deflate, or Brotli compression to response streams when requested by the client Accept-Encoding header.

function compression(options?: CompressionOptions): Handler

3. Multipart File Uploads

fileUpload

Streaming multipart/form-data upload middleware providing single, array, and field configurations.

// Single file uploadfileUpload.single(fieldName: string, options?: FileUploadOptions): Handler
// Multiple files under the same field namefileUpload.array(fieldName: string, maxCount?: number, options?: FileUploadOptions): Handler
// Multiple distinct fieldsfileUpload.fields(fields: { name: string; maxCount?: number }[], options?: FileUploadOptions): Handler
// Any files acceptedfileUpload.any(options?: FileUploadOptions): Handler
// Text fields onlyfileUpload.none(options?: FileUploadOptions): Handler

FileUploadOptions

OptionTypeDescription
deststringTarget directory on disk to stream uploaded files to.
maxBytesnumberMaximum allowed individual file size in bytes.
mimeTypesstring[]Permitted MIME types (e.g. ['image/png', 'image/jpeg']).
limitsFileUploadLimitsDetailed limits (fileSize, files, fieldSize, fields, parts).

Default limits (applied when a route does not set its own): files: 10, fields: 100, parts: 200, fieldSize: 1 MB, and fileSize equal to the app bodyLimit (10 MB by default). Exceeding a limit returns 413 Payload Too Large. Files written to disk are named <field>-<uuid><ext>; field names and extensions are sanitized, so client input cannot choose the path.

Example

src/http/users/route.ts
import { controller, route } from 'exisjs/router'import { fileUpload } from 'exisjs/middleware'
export default controller({  uploadAvatar: route.post('/avatar', {    middleware: [fileUpload.single('avatar', {      maxBytes: 5 * 1024 * 1024,      mimeTypes: ['image/png', 'image/jpeg'],    })],    async handle({ req }) {      const file = req.file // UploadedFile { filename, originalname, mimetype, size, buffer }      return { success: true, filename: file.filename }    },  }),})

fromExpress(middleware)

Adapts standard Express/Connect middleware to run within the ExisJS pipeline.

import { fromExpress } from 'exisjs/middleware'import morgan from 'morgan'
app.use(fromExpress(morgan('combined')))

4. Utility Middlewares

MiddlewareSignatureDescription
requestId()() => HandlerInjects a unique X-Request-Id into request and response headers.
requestLogger(options?)(options?: LoggerConfig) => HandlerFormats and logs request completion timings and status codes.
serveStatic(root, options?)(root: string, options?: StaticOptions) => HandlerServes static assets from disk with caching headers and streaming backpressure.
conditionalGet()() => HandlerTurns on automatic ETags and 304 Not Modified for the routes it is applied to (as etag: true does app-wide).
validate(schema)(schema: ValidateSchema) => HandlerValidates request parameters against a TexEngine schema.