From 1a596217b7d3e0d4c34820a6942575830e2eea2f Mon Sep 17 00:00:00 2001 From: John Date: Mon, 5 Oct 2026 19:12:24 +0530 Subject: [PATCH] rate-limit,cors --- .env | 7 ++++ node_modules/.package-lock.json | 63 ++++++++++++++++++++++++++++++++ package-lock.json | 65 +++++++++++++++++++++++++++++++++ package.json | 2 + server.js | 41 +++++++++++++++++++-- 5 files changed, 175 insertions(+), 3 deletions(-) diff --git a/.env b/.env index 6aae97b..90b2329 100644 --- a/.env +++ b/.env @@ -1,5 +1,12 @@ PORT=5000 NODE_ENV=production +# ─── CORS ───────────────────────────────────────────────── +# Comma-separated list of EXACT origins (scheme+host+port) allowed to make +# credentialed (cookie-carrying) requests to this API. Leave blank to reflect +# any origin back (fine on a private LAN — this is today's default). Once +# this app has a real public domain, set it, e.g.: +# CORS_ALLOWED_ORIGINS=https://portal.mitraindustries.com +CORS_ALLOWED_ORIGINS=https://erp.miplapp.in # NOTE: The following app settings moved OUT of .env and are now edited from # the Admin panel (System Settings tab), persisted in the app DB table # ZAPP_SETTINGS (see services/appSettingsStore.js): BOM approval levels, skip diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index 7f57158..7adbc6a 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -1833,6 +1833,48 @@ "url": "https://opencollective.com/express" } }, + "node_modules/express-rate-limit": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.0.tgz", + "integrity": "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "ip-address": "^10.2.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/express-rate-limit/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/express-rate-limit/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/express-validator": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.3.1.tgz", @@ -2288,6 +2330,18 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.3.0.tgz", + "integrity": "sha512-Qgpiaws3Sm30Av8Eah6sjMCZZwjlBu+E68rhpCWBshY1lb09HtLwj5GviX0OyQIn+ulUS0iX0AxN5n3tLZzz1w==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/EvanHahn" + } + }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -2456,6 +2510,15 @@ "node": ">= 0.4" } }, + "node_modules/ip-address": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.3.tgz", + "integrity": "sha512-A1kdq/tSb5QjvKvAMgIoEvDBIgL7qaqVP/jkvSwYYRZ9iEzvPpopxp2wQfu3SuZRHtpHNxMn8Fs0bS+gf5Xmwg==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", diff --git a/package-lock.json b/package-lock.json index e85b8e9..b79b77c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,8 +16,10 @@ "dotenv": "^16.6.1", "exceljs": "^4.4.0", "express": "^4.18.2", + "express-rate-limit": "^8.7.0", "express-validator": "^7.0.1", "form-data": "^4.0.5", + "helmet": "^8.3.0", "jsonwebtoken": "^9.0.2", "morgan": "^1.10.0", "mssql": "^9.0.0", @@ -2285,6 +2287,48 @@ "url": "https://opencollective.com/express" } }, + "node_modules/express-rate-limit": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.0.tgz", + "integrity": "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "ip-address": "^10.2.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/express-rate-limit/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/express-rate-limit/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/express-validator": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.3.1.tgz", @@ -2755,6 +2799,18 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.3.0.tgz", + "integrity": "sha512-Qgpiaws3Sm30Av8Eah6sjMCZZwjlBu+E68rhpCWBshY1lb09HtLwj5GviX0OyQIn+ulUS0iX0AxN5n3tLZzz1w==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/EvanHahn" + } + }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -2923,6 +2979,15 @@ "node": ">= 0.4" } }, + "node_modules/ip-address": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.3.tgz", + "integrity": "sha512-A1kdq/tSb5QjvKvAMgIoEvDBIgL7qaqVP/jkvSwYYRZ9iEzvPpopxp2wQfu3SuZRHtpHNxMn8Fs0bS+gf5Xmwg==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", diff --git a/package.json b/package.json index d62b6f6..15912bd 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,10 @@ "dotenv": "^16.6.1", "exceljs": "^4.4.0", "express": "^4.18.2", + "express-rate-limit": "^8.7.0", "express-validator": "^7.0.1", "form-data": "^4.0.5", + "helmet": "^8.3.0", "jsonwebtoken": "^9.0.2", "morgan": "^1.10.0", "mssql": "^9.0.0", diff --git a/server.js b/server.js index 932c0ec..20c505f 100644 --- a/server.js +++ b/server.js @@ -4,6 +4,8 @@ require('dotenv').config(); const express = require('express'); const cors = require('cors'); +const helmet = require('helmet'); +const rateLimit = require('express-rate-limit'); const path = require('path'); const jwt = require('jsonwebtoken'); const { body, validationResult } = require('express-validator'); @@ -18,7 +20,40 @@ app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ limit: '50mb', extended: true })); // Audit trail — records every mutating /api request (must be after body parsers) app.use(require('./middleware/auditLogger')); -app.use(cors({ origin: true, credentials: true })); +// Baseline security headers (X-Content-Type-Options, X-Frame-Options, HSTS, +// etc.). CSP is left off — this app serves lots of inline