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

@@ -3,6 +3,7 @@ const fs = require('fs-extra')
const MessageModel = require('../models/MessageModel')
const ALLOWED_SELF_DESTRUCT_SECONDS = [10, 30, 60, 300, 3600]
const DELETE_WINDOW_MS = 24 * 60 * 60 * 1000
function parseSelfDestructSeconds(raw) {
if (raw == null || raw === '' || raw === '0' || raw === 0) return null
@@ -22,15 +23,47 @@ function activeMessageFilter(baseFilter) {
baseFilter,
{
$or: [
{ expiresAt: { $exists: false } },
{ expiresAt: null },
{ expiresAt: { $gt: new Date() } }
{
selfDestructSeconds: { $exists: true, $ne: null },
selfDestructStartedAt: { $exists: false }
},
{
selfDestructSeconds: { $exists: true, $ne: null },
selfDestructStartedAt: { $exists: true, $ne: null },
$or: [
{ expiresAt: { $exists: false } },
{ expiresAt: null },
{ expiresAt: { $gt: new Date() } }
]
},
{
$and: [
{
$or: [
{ selfDestructSeconds: { $exists: false } },
{ selfDestructSeconds: null }
]
},
{
$or: [
{ expiresAt: { $exists: false } },
{ expiresAt: null },
{ expiresAt: { $gt: new Date() } }
]
}
]
}
]
}
]
}
}
function isWithinDeleteWindow(createdAt) {
if (!createdAt) return false
return Date.now() - new Date(createdAt).getTime() <= DELETE_WINDOW_MS
}
async function removeMessageFiles(messages) {
for (const msg of messages) {
if (!msg.file) continue
@@ -118,12 +151,86 @@ function scheduleMessageExpiry(io, message) {
scheduledTimers.set(id, timer)
}
async function startSelfDestructOnView(io, message, viewerId) {
if (!message?.selfDestructSeconds || message.selfDestructStartedAt) {
return message
}
const viewer = String(viewerId)
const receiver = String(message.receiverId)
if (viewer !== receiver) return message
const expiresAt = buildExpiresAt(message.selfDestructSeconds)
const updated = await MessageModel.findByIdAndUpdate(
message._id,
{
$set: {
selfDestructStartedAt: new Date(),
expiresAt
}
},
{ new: true }
)
if (updated) {
scheduleMessageExpiry(io, updated)
if (io) {
const sid = String(updated.senderId)
const rid = String(updated.receiverId)
io.to(`chat:${sid}:${rid}`)
.to(`chat:${rid}:${sid}`)
.emit('messageSelfDestructStarted', {
messageId: String(updated._id),
expiresAt: updated.expiresAt.toISOString(),
selfDestructSeconds: updated.selfDestructSeconds
})
}
}
return updated || message
}
async function markSelfDestructViewed(io, messageId, viewerId) {
const msg = await MessageModel.findById(messageId)
if (!msg || !msg.selfDestructSeconds || msg.selfDestructStartedAt) {
return { message: msg }
}
const updated = await startSelfDestructOnView(io, msg, viewerId)
return {
message: updated,
expiresAt: updated?.expiresAt
? new Date(updated.expiresAt).toISOString()
: undefined
}
}
async function startPendingSelfDestructForViewer(io, viewerId, peerId) {
const viewer = String(viewerId)
const peer = String(peerId)
const pending = await MessageModel.find({
receiverId: viewer,
senderId: peer,
selfDestructSeconds: { $exists: true, $ne: null },
selfDestructStartedAt: { $exists: false }
})
await Promise.all(
pending.map((msg) => startSelfDestructOnView(io, msg, viewer))
)
}
module.exports = {
ALLOWED_SELF_DESTRUCT_SECONDS,
DELETE_WINDOW_MS,
parseSelfDestructSeconds,
buildExpiresAt,
activeMessageFilter,
isWithinDeleteWindow,
purgeExpiredMessages,
scheduleMessageExpiry,
deleteMessagesAndNotify
deleteMessagesAndNotify,
startSelfDestructOnView,
markSelfDestructViewed,
startPendingSelfDestructForViewer
}