feat: Implement JSON serialization for message attachments with decryption support

This commit is contained in:
k1ngsterr1
2026-01-13 05:04:05 +05:00
parent af10005879
commit f6409a9474
3 changed files with 223 additions and 4 deletions

View File

@@ -7,6 +7,8 @@ import com.rosetta.messenger.database.*
import com.rosetta.messenger.network.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import org.json.JSONArray
import org.json.JSONObject
import java.util.UUID
/**
@@ -152,6 +154,9 @@ class MessageRepository private constructor(private val context: Context) {
toPublicKey
)
// Сериализуем attachments в JSON
val attachmentsJson = serializeAttachments(attachments)
// Сохраняем в БД
val entity = MessageEntity(
account = account,
@@ -165,7 +170,7 @@ class MessageRepository private constructor(private val context: Context) {
delivered = DeliveryStatus.WAITING.value,
messageId = messageId,
plainMessage = text.trim(),
attachments = "[]", // TODO: JSON serialize
attachments = attachmentsJson,
replyToMessageId = replyToMessageId,
dialogKey = dialogKey
)
@@ -218,6 +223,13 @@ class MessageRepository private constructor(private val context: Context) {
privateKey
)
// Сериализуем attachments в JSON с расшифровкой MESSAGES blob
val attachmentsJson = serializeAttachmentsWithDecryption(
packet.attachments,
packet.chachaKey,
privateKey
)
// Сохраняем в БД
val entity = MessageEntity(
account = account,
@@ -231,7 +243,7 @@ class MessageRepository private constructor(private val context: Context) {
delivered = DeliveryStatus.DELIVERED.value,
messageId = packet.messageId,
plainMessage = plainText,
attachments = "[]", // TODO
attachments = attachmentsJson,
dialogKey = dialogKey
)
messageDao.insertMessage(entity)
@@ -417,4 +429,92 @@ class MessageRepository private constructor(private val context: Context) {
lastSeen = lastSeen,
verified = verified == 1
)
/**
* Сериализация attachments в JSON
*/
private fun serializeAttachments(attachments: List<MessageAttachment>): String {
if (attachments.isEmpty()) return "[]"
val jsonArray = JSONArray()
for (attachment in attachments) {
val jsonObj = JSONObject().apply {
put("id", attachment.id)
put("blob", attachment.blob)
put("type", attachment.type.value)
put("preview", attachment.preview)
put("width", attachment.width)
put("height", attachment.height)
}
jsonArray.put(jsonObj)
}
return jsonArray.toString()
}
/**
* Сериализация attachments в JSON с расшифровкой MESSAGES blob
* Для MESSAGES типа blob расшифровывается и сохраняется в preview (как в RN)
*/
private fun serializeAttachmentsWithDecryption(
attachments: List<MessageAttachment>,
encryptedKey: String,
privateKey: String
): String {
if (attachments.isEmpty()) return "[]"
val jsonArray = JSONArray()
for (attachment in attachments) {
val jsonObj = JSONObject()
// Для MESSAGES типа расшифровываем blob
if (attachment.type == AttachmentType.MESSAGES && attachment.blob.isNotEmpty()) {
try {
val decryptedBlob = MessageCrypto.decryptAttachmentBlob(
attachment.blob,
encryptedKey,
privateKey
)
if (decryptedBlob != null) {
// Сохраняем расшифрованный JSON в preview (как в RN)
jsonObj.put("id", attachment.id)
jsonObj.put("blob", decryptedBlob) // Расшифрованный JSON
jsonObj.put("type", attachment.type.value)
jsonObj.put("preview", decryptedBlob) // Для совместимости
jsonObj.put("width", attachment.width)
jsonObj.put("height", attachment.height)
android.util.Log.d("MessageRepository", "✅ Decrypted MESSAGES blob: ${decryptedBlob.take(100)}")
} else {
// Fallback - сохраняем как есть
jsonObj.put("id", attachment.id)
jsonObj.put("blob", attachment.blob)
jsonObj.put("type", attachment.type.value)
jsonObj.put("preview", attachment.preview)
jsonObj.put("width", attachment.width)
jsonObj.put("height", attachment.height)
}
} catch (e: Exception) {
android.util.Log.e("MessageRepository", "❌ Failed to decrypt MESSAGES blob", e)
// Fallback - сохраняем как есть
jsonObj.put("id", attachment.id)
jsonObj.put("blob", attachment.blob)
jsonObj.put("type", attachment.type.value)
jsonObj.put("preview", attachment.preview)
jsonObj.put("width", attachment.width)
jsonObj.put("height", attachment.height)
}
} else {
// Для других типов сохраняем как есть
jsonObj.put("id", attachment.id)
jsonObj.put("blob", attachment.blob)
jsonObj.put("type", attachment.type.value)
jsonObj.put("preview", attachment.preview)
jsonObj.put("width", attachment.width)
jsonObj.put("height", attachment.height)
}
jsonArray.put(jsonObj)
}
return jsonArray.toString()
}
}