-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(security): add security middlewares and logging configuration
- Loading branch information
Showing
4 changed files
with
96 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,35 @@ | ||
import express from "express"; | ||
import { PORT } from "./config"; | ||
import { morganMiddleware, logger } from "./middleware/logging.middleware"; | ||
import { | ||
helmetMiddleware, | ||
corsMiddleware, | ||
rateLimitMiddleware, | ||
compressionMiddleware, | ||
} from "./middleware/security.middleware"; | ||
|
||
const app = express(); | ||
|
||
// Security middlewares | ||
app.use(helmetMiddleware); | ||
app.use(corsMiddleware); | ||
app.use(rateLimitMiddleware); | ||
app.use(compressionMiddleware); | ||
|
||
// Log HTTP requests | ||
app.use(morganMiddleware); | ||
|
||
// Parse JSON payloads | ||
app.use(express.json({ limit: "10kb" })); // The request payload should not exceed 10kb | ||
|
||
app.get("/", (_req, res) => { | ||
res.json({ message: "Hello World" }); | ||
res | ||
.json({ | ||
message: "Hello World", | ||
}) | ||
.status(200); | ||
}); | ||
|
||
app.listen(PORT, () => { | ||
console.log(`Server is running on http://localhost:${PORT}`); | ||
logger.info(`Server is running on http://localhost:${PORT}`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import winston from "winston"; | ||
import morgan from "morgan"; | ||
|
||
// Winston logger configuration | ||
export const logger = winston.createLogger({ | ||
level: process.env.NODE_ENV === "production" ? "info" : "debug", | ||
format: winston.format.combine( | ||
winston.format.colorize(), | ||
winston.format.timestamp(), | ||
winston.format.printf(({ timestamp, level, message }) => { | ||
return `${timestamp} ${level}: ${message}`; | ||
}), | ||
), | ||
transports: [new winston.transports.Console()], | ||
}); | ||
|
||
// Morgan (HTTP request logger middleware) configuration | ||
export const morganMiddleware = morgan("tiny", { | ||
stream: { | ||
write: (message) => logger.http(message.trim()), | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import helmet from "helmet"; | ||
import cors from "cors"; | ||
import rateLimit from "express-rate-limit"; | ||
import compression from "compression"; | ||
import { CORS_ORIGIN } from "../config"; | ||
|
||
// Basic CORS configuration | ||
export const corsMiddleware = cors({ | ||
origin: CORS_ORIGIN, | ||
methods: ["GET", "POST", "PUT", "DELETE", "PATCH"], | ||
credentials: true, | ||
}); | ||
|
||
// Rate limiting to prevent brute-force attacks | ||
export const rateLimitMiddleware = rateLimit({ | ||
windowMs: 15 * 60 * 1000, // 15 minutes | ||
max: 100, // Limit each IP to 100 requests per windowMs | ||
message: "Too many requests from this IP, please try again later", | ||
}); | ||
|
||
// Compression middleware | ||
export const compressionMiddleware = compression(); | ||
|
||
// Helmet middleware with security configurations | ||
export const helmetMiddleware = helmet({ | ||
contentSecurityPolicy: { | ||
directives: { | ||
defaultSrc: ["'self'"], | ||
scriptSrc: ["'self'", "'unsafe-inline'"], | ||
styleSrc: ["'self'", "'unsafe-inline'"], | ||
imgSrc: ["'self'", "data:", "https:"], | ||
}, | ||
}, | ||
crossOriginEmbedderPolicy: true, | ||
crossOriginOpenerPolicy: true, | ||
crossOriginResourcePolicy: true, | ||
dnsPrefetchControl: true, | ||
frameguard: true, | ||
hidePoweredBy: true, | ||
hsts: true, | ||
ieNoOpen: true, | ||
noSniff: true, | ||
originAgentCluster: true, | ||
permittedCrossDomainPolicies: true, | ||
referrerPolicy: true, | ||
xssFilter: true, | ||
}); |