feat: Implement JSON serialization for message attachments with decryption support
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user