This commit is contained in:
payacom
2026-08-31 20:45:41 +03:30
parent fa9f23c61d
commit 3f416a7a60
367 changed files with 621895 additions and 6443 deletions

View File

@@ -1,17 +1,57 @@
const bodyParser = require('body-parser')
const cors = require('cors')
const formData = require('express-form-data')
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) => {
app.use(cors()) // develop
app.use(formData.parse())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(session({
secret: 'your_secret_key', // کلید مخفی برای امنیت جلسات
resave: false,
saveUninitialized: false
}))
app.use(dispatchSession)
app.use(lastOnline)
}