const BLOCK_TIERS = [ { threshold: 15, durationMs: null, permanent: true }, { threshold: 10, durationMs: 30 * 24 * 60 * 60 * 1000 }, { threshold: 5, durationMs: 7 * 24 * 60 * 60 * 1000 }, { threshold: 3, durationMs: 24 * 60 * 60 * 1000 }, ] const formatRemainingPersian = (blockedUntil) => { if (!blockedUntil) return '' const diffMs = new Date(blockedUntil).getTime() - Date.now() if (diffMs <= 0) return '' const totalMinutes = Math.ceil(diffMs / (60 * 1000)) const days = Math.floor(totalMinutes / (24 * 60)) const hours = Math.floor((totalMinutes % (24 * 60)) / 60) const minutes = totalMinutes % 60 const parts = [] if (days > 0) parts.push(`${days} روز`) if (hours > 0) parts.push(`${hours} ساعت`) if (minutes > 0 || parts.length === 0) parts.push(`${minutes} دقیقه`) return parts.join(' و ') } const getBlockTier = (blockCount) => { return BLOCK_TIERS.find((tier) => blockCount >= tier.threshold) || null } const applyAutoBlockSuspension = (user) => { const blockCount = user.blocked_by?.length || 0 const tier = getBlockTier(blockCount) if (!tier) { if (user.block_permanent && user.account_status === 'deactivated') { user.account_status = 'active' } user.block_status = null user.blocked_until = null user.block_permanent = false return } user.block_status = true if (tier.permanent) { user.block_permanent = true user.blocked_until = null user.account_status = 'deactivated' return } user.block_permanent = false const currentUntil = user.blocked_until ? new Date(user.blocked_until).getTime() : 0 const newUntil = Date.now() + tier.durationMs if (!user.blocked_until || newUntil > currentUntil) { user.blocked_until = new Date(newUntil) } } const clearAutoBlockSuspension = (user) => { applyAutoBlockSuspension(user) } const isUserCurrentlyBlocked = (user) => { if (!user?.block_status) { return false } if (user.block_permanent) { return true } if (user.blocked_until) { if (new Date() >= new Date(user.blocked_until)) { return false } return true } return user.block_status === true } const expireBlockSuspensionIfNeeded = async (user) => { if (user.block_permanent) { return user } if (!user.blocked_until) { return user } if (new Date() >= new Date(user.blocked_until)) { const blockCount = user.blocked_by?.length || 0 applyAutoBlockSuspension(user) if (!isUserCurrentlyBlocked(user)) { user.block_status = null user.blocked_until = null } try { await user.save({ validateModifiedOnly: true }) } catch (saveError) { console.error('[expireBlockSuspensionIfNeeded] save failed:', saveError) } } return user } const getBlockedAccountResponse = (user) => { if (!isUserCurrentlyBlocked(user)) { return null } if (user.block_permanent || (user.blocked_by?.length || 0) >= 15) { return { status: 'error', code: 403, message: 'کاربر گرامی اکانت شما به علت تخلف زیاد و گزارش توسط کاربران دیگر غیر فعال می باشد.', type: 'block', blocked_until: null, permanent: true, } } const remaining = formatRemainingPersian(user.blocked_until) return { status: 'error', code: 403, message: remaining ? `به مدت ${remaining} از انجام هر گونه عملیات در سایت مسدود هستید.` : 'حساب کاربری شما موقتاً مسدود شده است.', type: 'block', blocked_until: user.blocked_until || null, permanent: false, } } module.exports = { BLOCK_TIERS, applyAutoBlockSuspension, clearAutoBlockSuspension, isUserCurrentlyBlocked, expireBlockSuspensionIfNeeded, getBlockedAccountResponse, formatRemainingPersian, }