Spaces:
Sleeping
Sleeping
File size: 2,515 Bytes
1758540 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import express, { type Express } from "express";
import cors from "cors";
import pinoHttp from "pino-http";
import { rateLimit } from "express-rate-limit";
import router from "./routes";
import { logger } from "./lib/logger";
const app: Express = express();
app.use(
pinoHttp({
logger,
serializers: {
req(req) {
return {
id: req.id,
method: req.method,
url: req.url?.split("?")[0],
};
},
res(res) {
return {
statusCode: res.statusCode,
};
},
},
}),
);
const allowedOrigins = process.env.ALLOWED_ORIGINS
? process.env.ALLOWED_ORIGINS.split(",")
: ["http://localhost:5173", "http://localhost:3000"];
app.use(cors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error("Not allowed by CORS"));
}
},
credentials: true,
}));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// A) General API limiter for all /api routes: window 15 mins, max 500 requests per IP
const generalApiLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 500,
message: "طلبات كثيرة جداً، حاول مجدداً بعد قليل",
standardHeaders: true,
legacyHeaders: false,
skip: (req) => process.env.NODE_ENV === "test" || req.headers["x-bypass-rate-limit"] === "true",
});
// B) Auth limiter strictly on /api/auth/login: window 15 mins, max 10 attempts per IP
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 10,
message: "محاولات تسجيل دخول كثيرة، انتظر 15 دقيقة",
standardHeaders: true,
legacyHeaders: false,
skip: (req) => process.env.NODE_ENV === "test" || req.headers["x-bypass-rate-limit"] === "true",
});
// C) Upload limiter for attachments/upload routes: window 1 hour, max 50 uploads per IP
const uploadLimiter = rateLimit({
windowMs: 60 * 60 * 1000,
max: 50,
message: "تجاوزت حد الرفع المسموح به",
standardHeaders: true,
legacyHeaders: false,
skip: (req) => process.env.NODE_ENV === "test" || req.headers["x-bypass-rate-limit"] === "true",
});
// Apply Rate Limiters before the router middleware
app.use("/api/auth/login", authLimiter);
app.use("/api/attachments", uploadLimiter);
app.use("/api/upload", uploadLimiter);
app.use("/api/tasks/:id/attachments", uploadLimiter);
app.use("/api", generalApiLimiter);
app.use("/api", router);
export default app;
|