Files
modstagram-back/middlewares/index.js
payacom d4ebc20aa8 reels
2026-10-01 21:12:05 +03:30

61 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const bodyParser = require('body-parser')
const session = require('express-session')
const { RedisStore } = require('connect-redis')
const { getRedisClient, getRawClient } = require('../utils/redisClient')
const lastOnline = require('./lastOnline')
const SESSION_OPTIONS = {
secret: process.env.SESSION_SECRET || process.env.JWT_SECRET || 'change-me-in-production',
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
},
}
// قبلاً MemoryStoreِ پیش‌فرضِ express-session بود — برای production مناسب نیست (نه
// بین چند اینستنس‌سرور مشترکه، نه محدودیتی داره). الان وقتی Redis وصله از یه store
// مشترک استفاده می‌شه. عین ratedLimiter (createRateLimiter.js): دو نمونه‌ی کاملاً
// جدا ساخته می‌شه و روی *هر* درخواست بر اساسِ آماده‌بودنِ فعلیِ Redis سوییچ می‌شه —
// نه اینکه همیشه به Redis وصل بشه و فقط منتظرِ خطا بمونه. اون روش (client خام،
// بدون چکِ آماده‌بودن) وقتی Redis اصلاً هیچ‌وقت در دسترس نبود (مثلاً یه دیپلویِ
// تازه که هنوز Redis روش ست نشده)، هر درخواست رو تا انقضای connectTimeout کند
// می‌کرد؛ این نسخه اون تأخیر رو صفر می‌کنه چون اصلاً منتظرِ Redis نمی‌مونه
const redisSession = session({
...SESSION_OPTIONS,
store: new RedisStore({ client: getRawClient(), prefix: 'sess:' }),
})
const memorySession = session(SESSION_OPTIONS)
// نکته: اگه Redis وسطِ یه session بیفته (بعد از ساخته‌شدن یه سشنِ Redis-محور)،
// سوییچ به memorySession یعنی اون سشنِ خاص موقتاً دیده نمی‌شه — قابل‌قبوله چون این
// اپ اصلی‌ترین احرازهویتش JWTه، نه سشن (req.session جای دیگه‌ای توی این کدبیس
// استفاده نمی‌شه)
function dispatchSession (req, res, next) {
const store = getRedisClient() ? redisSession : memorySession
store(req, res, (err) => {
if (err) {
// fallback نهایی برای همون ریسِ نادرِ «Redis درست وسطِ همین درخواست قطع شد» —
// به‌جای next(err) (که express-session پیش‌فرضش ۵۰۰-کردنِ کل درخواسته)، فقط
// لاگ می‌کنیم و بدون سشن ادامه می‌دیم
console.error('[session] store error — continuing without session:', err.message)
return next()
}
next()
})
}
module.exports = (app) => {
// express-form-data قبلاً اینجا global و بدون هیچ استثنایی نصب بود — بدنه‌ی هر
// درخواست multipart رو (پست/استوری ویدیو و هر آپلودِ دیگه) کامل می‌خوند و مصرف
// می‌کرد، درحالی‌که هیچ‌جای کدبیس از خروجیِ خودش استفاده نمی‌کرد؛ فقط باعث می‌شد
// وقتی نوبت به multer (همونی که این روت‌ها واقعاً استفاده می‌کنن) می‌رسید، دیگه
// هیچ بایتی از بدنه باقی نمونده باشه (busboy با «Unexpected end of form» شکست می‌خورد)
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(dispatchSession)
app.use(lastOnline)
}