import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:pointycastle/pointycastle.dart'; import 'package:uuid/uuid.dart'; import '/database/models/image_message.dart'; import '/database/models/conversation_users.dart'; import '/database/models/my_profile.dart'; import '/database/models/text_messages.dart'; import '/database/models/conversations.dart'; import '/utils/encryption/crypto_utils.dart'; import '/utils/storage/database.dart'; const messageTypeReceiver = 'receiver'; const messageTypeSender = 'sender'; Future> getMessagesForThread(Conversation conversation) async { final db = await getDatabaseConnection(); final List> maps = await db.rawQuery( ''' SELECT * FROM messages WHERE association_key IN ( SELECT association_key FROM conversation_users WHERE conversation_id = ? ) ORDER BY created_at DESC; ''', [conversation.id] ); return List.generate(maps.length, (i) { if (maps[i]['data'] == null) { File file = File(maps[i]['file']); return ImageMessage( id: maps[i]['id'], symmetricKey: maps[i]['symmetric_key'], userSymmetricKey: maps[i]['user_symmetric_key'], file: file, senderId: maps[i]['sender_id'], senderUsername: maps[i]['sender_username'], associationKey: maps[i]['association_key'], createdAt: maps[i]['created_at'], failedToSend: maps[i]['failed_to_send'] == 1, ); } return TextMessage( id: maps[i]['id'], symmetricKey: maps[i]['symmetric_key'], userSymmetricKey: maps[i]['user_symmetric_key'], text: maps[i]['data'], senderId: maps[i]['sender_id'], senderUsername: maps[i]['sender_username'], associationKey: maps[i]['association_key'], createdAt: maps[i]['created_at'], failedToSend: maps[i]['failed_to_send'] == 1, ); }); } class Message { String id; String symmetricKey; String userSymmetricKey; String senderId; String senderUsername; String associationKey; String createdAt; bool failedToSend; Message({ required this.id, required this.symmetricKey, required this.userSymmetricKey, required this.senderId, required this.senderUsername, required this.associationKey, required this.createdAt, required this.failedToSend, }); Future>> payloadJsonBase( Uint8List symmetricKey, Uint8List userSymmetricKey, Conversation conversation, String messageId, String messageDataId, ) async { MyProfile profile = await MyProfile.getProfile(); if (profile.publicKey == null) { throw Exception('Could not get profile.publicKey'); } RSAPublicKey publicKey = profile.publicKey!; List> messages = []; List conversationUsers = await getConversationUsers(conversation); for (var i = 0; i < conversationUsers.length; i++) { ConversationUser user = conversationUsers[i]; if (profile.id == user.userId) { messages.add({ 'id': messageId, 'message_data_id': messageDataId, 'symmetric_key': base64.encode(CryptoUtils.rsaEncrypt( userSymmetricKey, publicKey, )), 'association_key': user.associationKey, }); continue; } ConversationUser conversationUser = await getConversationUser(conversation, user.userId); RSAPublicKey friendPublicKey = conversationUser.publicKey; messages.add({ 'message_data_id': messageDataId, 'symmetric_key': base64.encode(CryptoUtils.rsaEncrypt( userSymmetricKey, friendPublicKey, )), 'association_key': user.associationKey, }); } return messages; } String getContent() { return ''; } Map toMap() { return { 'id': id, 'symmetric_key': symmetricKey, 'user_symmetric_key': userSymmetricKey, 'sender_id': senderId, 'sender_username': senderUsername, 'association_key': associationKey, 'created_at': createdAt, 'failed_to_send': failedToSend ? 1 : 0, }; } }