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 '/database/models/my_profile.dart';
|
|
import '/database/models/conversations.dart';
|
|
import '/database/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<ImageMessage> fromJson(Map<String, dynamic> 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(
|
|
'$defaultServerUrl/files/${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<String, dynamic> 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<Map<String, dynamic>> payloadJson(Conversation conversation) async {
|
|
final String messageDataId = (const Uuid()).v4();
|
|
|
|
final symmetricKey = AesHelper.deriveKey(generateRandomString(32));
|
|
|
|
final userSymmetricKey = AesHelper.deriveKey(generateRandomString(32));
|
|
|
|
List<Map<String, String>> messages = await super.payloadJsonBase(
|
|
symmetricKey,
|
|
userSymmetricKey,
|
|
conversation,
|
|
id,
|
|
messageDataId,
|
|
);
|
|
|
|
Map<String, dynamic> 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 <String, dynamic>{
|
|
'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
|
|
''';
|
|
}
|
|
}
|