full
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user