Samoulla Sync Bot
Auto-deploy Samoulla Backend: 8574a71f0fc617aeb1ce9b5e35dac24c5319a12a
59c49c1
const express = require('express');
const dotenv = require('dotenv');
dotenv.config({ path: './config.env' });
const morgan = require('morgan');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const mongoSanitize = require('express-mongo-sanitize');
const xss = require('xss-clean');
const hpp = require('hpp');
const compression = require('compression');
const cors = require('cors');
const AppError = require('./utils/appError');
const globalErrorHandler = require('./middlewares/errorMiddleware');
const productRouter = require('./routes/productRoutes');
const authRouter = require('./routes/authRoutes');
const cartRouter = require('./routes/cartRoutes');
const orderRouter = require('./routes/orderRoutes');
const promoRouter = require('./routes/promoRoutes');
const categoryRouter = require('./routes/categoryRoutes');
const brandRouter = require('./routes/brandRoutes');
const providerRouter = require('./routes/providerRoutes');
const reviewRouter = require('./routes/reviewRouter');
const addressRoutes = require('./routes/addressRoutes');
const favoriteRouter = require('./routes/favoriteRoutes');
const imageRouter = require('./routes/imageRoutes');
const usersRouter = require('./routes/usersRoutes');
const adminRouter = require('./routes/adminRoutes');
const vendorRouter = require('./routes/vendorRoutes');
const newsletterRouter = require('./routes/newsletterRoutes');
const notificationRouter = require('./routes/notificationRoutes');
const contentRouter = require('./routes/contentRoutes');
const permissionRouter = require('./routes/permissionRoutes');
const shippingRouter = require('./routes/shippingRoutes');
const financeRouter = require('./routes/financeRoutes');
const paymentRouter = require('./routes/paymentRoutes');
const vendorRequestRouter = require('./routes/vendorRequestRoutes');
const returnRequestRouter = require('./routes/returnRequestRoutes');
const visitRouter = require('./routes/visitRoutes');
const app = express();
app.set('trust proxy', 1);
// GLOBAL MIDDLEWARES
// Implement CORS
app.use(
cors({
origin: [
'http://localhost:5173',
'https://samoulla-web.vercel.app',
'https://samoulla.vercel.app',
'https://samoulla.com',
'https://www.samoulla.com',
process.env.FRONTEND_URL,
].filter(Boolean),
credentials: true,
}),
);
// Set security HTTP headers
app.use(helmet());
// Development logging
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
}
// Limit requests for auth routes (login/register/reset password)
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 200,
message:
'Too many authentication attempts. Please try again after 15 minutes.',
standardHeaders: true,
legacyHeaders: false,
validate: { trustProxy: false },
});
// Limit requests from same API (global browsing)
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: process.env.NODE_ENV === 'development' ? 10000 : 20000,
message: 'Too many requests from this IP, please try again in 15 minutes.',
standardHeaders: true,
legacyHeaders: false,
validate: { trustProxy: false },
});
app.use('/samoulla/v1/auth', authLimiter);
app.use('/samoulla', limiter);
// Body parser, reading data from body into req.body
app.use(express.json({ limit: '10kb' }));
// Data sanitization against NoSQL query injection
app.use(mongoSanitize());
// Data sanitization against XSS
app.use(xss());
// Prevent parameter pollution
app.use(
hpp({
whitelist: [
'price',
'ratingsAverage',
'ratingsQuantity',
'stock',
'brand',
'category',
],
}),
);
app.use(compression());
// HEALTH CHECK ROUTES (must stay lightweight and never be rate-limited)
app.get('/', (req, res) => {
res.status(200).json({
status: 'success',
message: 'Samoulla Backend is Alive and Runningg! 🚀',
});
});
app.get('/healthz', (req, res) => {
res.status(200).json({
status: 'success',
service: 'samoulla-backend',
uptime: process.uptime(),
timestamp: new Date().toISOString(),
});
});
app.get('/samoulla/v1/health', (req, res) => {
res.status(200).json({
status: 'success',
service: 'samoulla-backend',
uptime: process.uptime(),
timestamp: new Date().toISOString(),
});
});
// ROUTES
app.use('/samoulla/v1/products', productRouter);
app.use('/samoulla/v1/auth', authRouter);
app.use('/samoulla/v1/cart', cartRouter);
app.use('/samoulla/v1/orders', orderRouter);
app.use('/samoulla/v1/promos', promoRouter);
app.use('/samoulla/v1/categories', categoryRouter);
app.use('/samoulla/v1/brands', brandRouter);
app.use('/samoulla/v1/providers', providerRouter);
app.use('/samoulla/v1/reviews', reviewRouter);
app.use('/samoulla/v1/addresses', addressRoutes);
app.use('/samoulla/v1/favorites', favoriteRouter);
app.use('/samoulla/v1/images', imageRouter);
app.use('/samoulla/v1/users', usersRouter);
app.use('/samoulla/v1/admin', adminRouter);
app.use('/samoulla/v1/vendor', vendorRouter);
app.use('/samoulla/v1/newsletter', newsletterRouter);
app.use('/samoulla/v1/notifications', notificationRouter);
app.use('/samoulla/v1/content', contentRouter);
app.use('/samoulla/v1/permissions', permissionRouter);
app.use('/samoulla/v1/shipping', shippingRouter);
app.use('/samoulla/v1/finance', financeRouter);
app.use('/samoulla/v1/payment', paymentRouter);
app.use('/samoulla/v1/vendor-requests', vendorRequestRouter);
app.use('/samoulla/v1/return-requests', returnRequestRouter);
app.use('/samoulla/v1/visits', visitRouter);
app.all('*', (req, res, next) => {
next(new AppError(`Can't find ${req.originalUrl} on this server!`, 404));
});
app.use(globalErrorHandler);
module.exports = app;