full
This commit is contained in:
@@ -1,27 +1,77 @@
|
||||
const moment = require('moment-jalaali')
|
||||
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 BLOCK_THRESHOLD = 5
|
||||
const BLOCK_DURATION_MS = 7 * 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) => {
|
||||
if (user.blocked_by.length >= BLOCK_THRESHOLD) {
|
||||
user.block_status = true
|
||||
user.blocked_until = new Date(Date.now() + BLOCK_DURATION_MS)
|
||||
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) => {
|
||||
if (user.blocked_by.length < BLOCK_THRESHOLD && user.blocked_until) {
|
||||
user.block_status = null
|
||||
user.blocked_until = null
|
||||
}
|
||||
applyAutoBlockSuspension(user)
|
||||
}
|
||||
|
||||
const isUserCurrentlyBlocked = (user) => {
|
||||
if (!user.block_status) {
|
||||
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
|
||||
@@ -33,14 +83,26 @@ const isUserCurrentlyBlocked = (user) => {
|
||||
}
|
||||
|
||||
const expireBlockSuspensionIfNeeded = async (user) => {
|
||||
if (user.block_permanent) {
|
||||
return user
|
||||
}
|
||||
|
||||
if (!user.blocked_until) {
|
||||
return user
|
||||
}
|
||||
|
||||
if (new Date() >= new Date(user.blocked_until)) {
|
||||
user.block_status = null
|
||||
user.blocked_until = null
|
||||
await user.save()
|
||||
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
|
||||
@@ -51,27 +113,38 @@ const getBlockedAccountResponse = (user) => {
|
||||
return null
|
||||
}
|
||||
|
||||
const untilText = user.blocked_until
|
||||
? moment(user.blocked_until).format('jYYYY/jMM/jDD')
|
||||
: 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: untilText
|
||||
? `حساب کاربری شما به دلیل بلاک شدن توسط ${BLOCK_THRESHOLD} کاربر تا تاریخ ${untilText} غیرفعال است.`
|
||||
: 'حساب کاربری شما مسدود شده است، برای اطلاعات بیشتر با پشتیبانی تماس بگیرید!',
|
||||
message: remaining
|
||||
? `به مدت ${remaining} از انجام هر گونه عملیات در سایت مسدود هستید.`
|
||||
: 'حساب کاربری شما موقتاً مسدود شده است.',
|
||||
type: 'block',
|
||||
blocked_until: user.blocked_until || null
|
||||
blocked_until: user.blocked_until || null,
|
||||
permanent: false,
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
BLOCK_THRESHOLD,
|
||||
BLOCK_DURATION_MS,
|
||||
BLOCK_TIERS,
|
||||
applyAutoBlockSuspension,
|
||||
clearAutoBlockSuspension,
|
||||
isUserCurrentlyBlocked,
|
||||
expireBlockSuspensionIfNeeded,
|
||||
getBlockedAccountResponse
|
||||
getBlockedAccountResponse,
|
||||
formatRemainingPersian,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user