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,19 +1,49 @@
const jwt = require('jsonwebtoken')
const UserModel = require('../models/UserModel')
const { getRedisClient } = require('../utils/redisClient')
const { markOnline } = require('../utils/presence')
// این میدل‌ور روی *هر* درخواستِ احرازهویت‌شده اجرا می‌شه (app.use سراسری) — قبلاً
// یعنی هر درخواست یه findById+save کاملِ Mongo می‌زد، حتی برای کاربری که پشتِ‌سرِهم
// صدها درخواست در دقیقه می‌فرسته. الان: وضعیتِ «آنلاینِ لحظه‌ای» توی Redis با TTLِ
// کوتاه نگه داشته می‌شه (هر درخواست رفرش می‌شه، تقریباً رایگان — utils/presence.js)،
// و نوشتنِ last_online توی Mongo (برای «آخرین بازدید» که جاهای دیگه‌ی اپ می‌خونن)
// throttle می‌شه به حداکثر یک‌بار در هر ۶۰ ثانیه برای هر کاربر
const MONGO_SYNC_TTL_SECONDS = 60
async function syncLastOnlineToMongo (userId) {
const user = await UserModel.findById(userId).select('ghost_mode account_status')
if (user && !user.ghost_mode && user.account_status !== 'deactivated') {
await UserModel.updateOne({ _id: userId }, { last_online: new Date() })
}
}
module.exports = async (req, res, next) => {
if (req.header && req.header('Authorization')) {
const token = await req.header('Authorization').split(' ')[1]
const decodedToken = await jwt.verify(token, process.env.APP_SECRET)
const user = await UserModel.findById(decodedToken.id)
if (user) {
try {
user.last_online = new Date()
await user.save() // ذخیره تغییرات در دیتابیس
} catch (error) {
// بررسی و پردازش خطاها
console.error('Error updating last online time:', error)
try {
const token = req.header('Authorization').split(' ')[1]
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = String(decodedToken.id)
const redis = getRedisClient()
if (redis) {
await markOnline(userId)
const acquiredSyncLock = await redis.set(
`presence:sync:${userId}`,
'1',
{ NX: true, EX: MONGO_SYNC_TTL_SECONDS }
)
if (acquiredSyncLock) {
await syncLastOnlineToMongo(userId)
}
} else {
// Redis در دسترس نیست — همون رفتارِ قبلی، مستقیم Mongo (fallback امن، کندتر
// ولی درست) تا وقتی Redis دوباره وصل بشه
await syncLastOnlineToMongo(userId)
}
} catch (error) {
console.error('Error updating last online time:', error)
}
}