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<List<Message>> getMessagesForThread(Conversation conversation) async {
|
|
final db = await getDatabaseConnection();
|
|
|
|
final List<Map<String, dynamic>> 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<List<Map<String, String>>> 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<Map<String, String>> messages = [];
|
|
List<ConversationUser> 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<String, dynamic> 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,
|
|
};
|
|
}
|
|
}
|