Files
modstagram-back/utils/blockSuspension.js
payacom 3f416a7a60 full
2026-08-31 20:45:41 +03:30

151 lines
4.0 KiB
JavaScript

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,
}