This commit is contained in:
payacom
2026-09-13 21:32:36 +03:30
parent 90c5f94b57
commit c302aea177
49 changed files with 4063 additions and 920 deletions

View File

@@ -645,7 +645,33 @@ const putRoomE2eeKeys = async (req, res, next) => {
})
}
if (typeof e2ee_enabled === 'boolean') {
// فعال‌سازیِ اولیه‌ی E2EE روم باید atomic باشه — بدون این گارد، اگه دو عضو تقریباً
// هم‌زمان (هرکدوم با یه کلیدِ تصادفیِ متفاوت) اولین‌بار بخوان روم رو فعال کنن، هر دو
// findById/save رو با موفقیت رد می‌کردن و ذخیره‌ی دومی wrap های اولی رو override
// می‌کرد — نتیجه یه ناهم‌خوانیِ دائمیِ کلید بین اعضا بود؛ دقیقاً همون باگی که باعث
// شد E2EE روم‌ها موقتاً به‌طور کامل غیرفعال بشه به‌جای رفعِ ریشه‌ای
if (e2ee_enabled === true && !room.e2ee_enabled) {
const claimed = await ChatRoomModel.findOneAndUpdate(
{ _id: roomId, e2ee_enabled: { $ne: true } },
{ $set: { e2ee_enabled: true } },
{ new: true }
)
if (!claimed) {
// یکی دیگه هم‌زمان برنده شد — این درخواست نباید wrapped_keys خودش (که با
// کلیدِ بازنده ساخته شده) رو ثبت کنه؛ کلاینت باید myWrappedKey تازه (متعلق به
// کلیدِ برنده) رو بخونه و کلیدِ محلیِ خودش رو دور بریزه
const fresh = await ChatRoomModel.findById(roomId)
const freshWraps = Array.isArray(fresh?.e2ee_wrapped_keys) ? fresh.e2ee_wrapped_keys : []
const myFreshWrap = freshWraps.find((w) => String(w.userId) === userId)
return res.status(409).json({
error: 'room e2ee already enabled by another member',
code: 'E2EE_ALREADY_ENABLED',
e2ee_enabled: true,
myWrappedKey: myFreshWrap?.wrappedKey || null
})
}
room.e2ee_enabled = true
} else if (typeof e2ee_enabled === 'boolean') {
room.e2ee_enabled = e2ee_enabled
}