From fe8ba5e8a91f5ac4fe49a9fd47100cfad5c6a494 Mon Sep 17 00:00:00 2001 From: Andrew Besedin Date: Wed, 11 Feb 2026 16:08:26 +0300 Subject: [PATCH] add: add desired global setup for basic api security and reliability --- package-lock.json | 14 ++++++++++++ package.json | 1 + src/middleware/middleware.ts | 44 ++++++++++++++++++++++++++++++++++++ src/server.ts | 2 ++ 4 files changed, 61 insertions(+) diff --git a/package-lock.json b/package-lock.json index 7572876..f56c08f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "dotenv": "^16.0.3", "express": "^4.18.2", "express-rate-limit": "^8.2.1", + "express-validator": "^7.3.1", "jimp": "^0.22.8", "jsonwebtoken": "^9.0.0", "nanoid": "^5.1.5", @@ -4280,6 +4281,19 @@ "express": ">= 4.11" } }, + "node_modules/express-validator": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.3.1.tgz", + "integrity": "sha512-IGenaSf+DnWc69lKuqlRE9/i/2t5/16VpH5bXoqdxWz1aCpRvEdrBuu1y95i/iL5QP8ZYVATiwLFhwk3EDl5vg==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21", + "validator": "~13.15.23" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", diff --git a/package.json b/package.json index f5d7a74..8cec8ad 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "dotenv": "^16.0.3", "express": "^4.18.2", "express-rate-limit": "^8.2.1", + "express-validator": "^7.3.1", "jimp": "^0.22.8", "jsonwebtoken": "^9.0.0", "nanoid": "^5.1.5", diff --git a/src/middleware/middleware.ts b/src/middleware/middleware.ts index 8e50f66..11f2432 100644 --- a/src/middleware/middleware.ts +++ b/src/middleware/middleware.ts @@ -1,4 +1,5 @@ import { NextFunction, Request, Response } from 'express'; +import { ValidationChain, validationResult } from 'express-validator'; import { rateLimit } from 'express-rate-limit'; import jwt from 'jsonwebtoken'; import User from '@/schemes/User'; @@ -49,6 +50,49 @@ class Middleware { defaultRateLimit = async (req: Request, res: Response, next: NextFunction) => defaultRateLimitMiddleware(req, res, next); + expressValidator(validators: ValidationChain[]) { + return [ + ...validators, + (req: Request, res: Response, next: NextFunction) => { + const errors = validationResult(req); + + if (!errors.isEmpty()) { + res.status(500).send({ + success: false, + data: 'Internal error', + }); + return; + } + + next(); + }, + ]; + } + + expressJSONErrorHandler = (err: Error, req: Request, res: Response, next: NextFunction) => { + const isExpressJSONError = + err instanceof SyntaxError && 'status' in err && err.status === 400 && 'body' in err; + + if (isExpressJSONError) { + res.status(500).send({ + success: false, + data: 'Internal error', + }); + } else { + next(); + } + }; + + globalErrorHandler = (err: Error, req: Request, res: Response, _next: NextFunction) => { + console.error('Global error handler:'); + console.error(err); + res.status(500).send({ + success: false, + data: 'Internal error', + }); + }; + + resultGlobalErrorHandler = [this.expressJSONErrorHandler, this.globalErrorHandler]; } const middleware = new Middleware(); diff --git a/src/server.ts b/src/server.ts index ed5f774..4c20936 100644 --- a/src/server.ts +++ b/src/server.ts @@ -101,6 +101,8 @@ process.on('unhandledRejection', (reason, promise) => { res.send({ success: true, userData: req.body.userData }), ); + app.use(middleware.resultGlobalErrorHandler); + server.listen(PORT, () => console.log(`Server is running on port ${PORT}`)); })();