diff --git a/README.md b/README.md index 2ba6041..9e554e0 100644 --- a/README.md +++ b/README.md @@ -269,7 +269,7 @@ pnpm test --- -linked PR 5 +linked PR 5,4 ## 📄 License diff --git a/package.json b/package.json index 889c4c8..52988ce 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "jsonwebtoken": "9.0.2", "mongoose": "7.6.3", "uuid": "9.0.1", - "winston": "3.11.0" + "winston": "3.11.0", + "zod": "^4.4.3" }, "devDependencies": { "@types/bcryptjs": "2.4.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 633d702..9a3049e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,6 +43,9 @@ importers: winston: specifier: 3.11.0 version: 3.11.0 + zod: + specifier: ^4.4.3 + version: 4.4.3 devDependencies: '@types/bcryptjs': specifier: 2.4.6 @@ -4911,6 +4914,12 @@ packages: } engines: { node: '>=10' } + zod@4.4.3: + resolution: + { + integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==, + } + snapshots: '@babel/code-frame@7.29.7': dependencies: @@ -8063,3 +8072,5 @@ snapshots: yn@3.1.1: {} yocto-queue@0.1.0: {} + + zod@4.4.3: {} diff --git a/src/app.ts b/src/app.ts index 26ce4f6..4b10ccf 100644 --- a/src/app.ts +++ b/src/app.ts @@ -8,6 +8,7 @@ import logger from './config/logger'; import { corsOptionsDelegate, helmetOptions } from './config/security'; import errorHandler from './middleware/errorHandler'; import routes from './routes'; +import env from './config/env'; const app = express(); @@ -15,16 +16,18 @@ const app = express(); // secure headers and rate limiting use the correct client IP. app.set('trust proxy', 1); -// Secure HTTP headers (Helmet) -app.use(helmet(helmetOptions)); - -// Cross-Origin Resource Sharing restricted to the configured frontend origins -app.use(cors(corsOptionsDelegate)); +// CORS configuration +app.use( + cors({ + origin: env.CORS_ORIGIN, + credentials: true, + }), +); // Rate limiting const limiter = rateLimit({ - windowMs: 15 * 60 * 1000, // 15 minutes - max: 100, // Limit each IP to 100 requests per windowMs + windowMs: env.RATE_LIMIT_WINDOW_MS, + max: env.RATE_LIMIT_MAX_REQUESTS, standardHeaders: true, legacyHeaders: false, }); diff --git a/src/config/database.ts b/src/config/database.ts index 65bb270..caf1b2e 100644 --- a/src/config/database.ts +++ b/src/config/database.ts @@ -1,9 +1,10 @@ import mongoose from 'mongoose'; import logger from './logger'; +import env from './env'; export const connectDatabase = async (): Promise => { try { - const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/swiftchain'; + const mongoUri = env.MONGODB_URI; await mongoose.connect(mongoUri); diff --git a/src/server.ts b/src/server.ts index 4f34316..ec2c7ad 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,10 +1,11 @@ import app from './app'; import logger from './config/logger'; +import env from './config/env'; -const PORT = process.env.PORT || 3000; +const PORT = env.PORT; const server = app.listen(PORT, () => { - logger.info(`🚀 Server running on port ${PORT} in ${process.env.NODE_ENV} mode`); + logger.info(`🚀 Server running on port ${PORT} in ${env.NODE_ENV} mode`); logger.info(`📝 Health check: http://localhost:${PORT}/health`); });