import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:Envelope/utils/storage/get_file.dart'; import 'package:Envelope/utils/storage/write_file.dart'; import 'package:mime/mime.dart'; import 'package:pointycastle/pointycastle.dart'; import 'package:uuid/uuid.dart'; import '/models/conversations.dart'; import '/models/messages.dart'; import '/utils/encryption/aes_helper.dart'; import '/utils/encryption/crypto_utils.dart'; import '/utils/strings.dart'; class ImageMessage extends Message { File file; ImageMessage({ id, symmetricKey, userSymmetricKey, senderId, senderUsername, associationKey, createdAt, failedToSend, required this.file, }) : super( id: id, symmetricKey: symmetricKey, userSymmetricKey: userSymmetricKey, senderId: senderId, senderUsername: senderUsername, associationKey: associationKey, createdAt: createdAt, failedToSend: failedToSend, ); static Future fromJson(Map json, RSAPrivateKey privKey) async { var userSymmetricKey = CryptoUtils.rsaDecrypt( base64.decode(json['symmetric_key']), privKey, ); var symmetricKey = AesHelper.aesDecrypt( userSymmetricKey, base64.decode(json['message_data']['symmetric_key']), ); var senderId = AesHelper.aesDecrypt( base64.decode(symmetricKey), base64.decode(json['message_data']['sender_id']), ); File file = await getFile( json['message_data']['attachment']['image_link'], '${json['id']}', symmetricKey, ); return ImageMessage( id: json['id'], symmetricKey: symmetricKey, userSymmetricKey: base64.encode(userSymmetricKey), senderId: senderId, senderUsername: 'Unknown', associationKey: json['association_key'], createdAt: json['created_at'], failedToSend: false, file: file, ); } @override Map toMap() { return { 'id': id, 'symmetric_key': symmetricKey, 'user_symmetric_key': userSymmetricKey, 'file': file.path, 'sender_id': senderId, 'sender_username': senderUsername, 'association_key': associationKey, 'created_at': createdAt, 'failed_to_send': failedToSend ? 1 : 0, }; } Future> payloadJson(Conversation conversation) async { final String messageDataId = (const Uuid()).v4(); final symmetricKey = AesHelper.deriveKey(generateRandomString(32)); final userSymmetricKey = AesHelper.deriveKey(generateRandomString(32)); List> messages = await super.payloadJsonBase( symmetricKey, userSymmetricKey, conversation, id, messageDataId, ); Map messageData = { 'id': messageDataId, 'sender_id': AesHelper.aesEncrypt(symmetricKey, Uint8List.fromList(senderId.codeUnits)), 'symmetric_key': AesHelper.aesEncrypt( userSymmetricKey, Uint8List.fromList(base64.encode(symmetricKey).codeUnits), ), 'attachment': { 'data': AesHelper.aesEncrypt(base64.encode(symmetricKey), Uint8List.fromList(file.readAsBytesSync())), 'mimetype': lookupMimeType(file.path), 'extension': getExtension(file.path), } }; return { 'message_data': messageData, 'message': messages, }; } @override String getContent() { return 'Image'; } @override String toString() { return ''' id: $id file: ${file.path}, senderId: $senderId senderUsername: $senderUsername associationKey: $associationKey createdAt: $createdAt '''; } }