Encrypted messaging app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.6 KiB

  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'dart:typed_data';
  4. import 'package:Envelope/utils/storage/get_file.dart';
  5. import 'package:Envelope/utils/storage/write_file.dart';
  6. import 'package:mime/mime.dart';
  7. import 'package:pointycastle/pointycastle.dart';
  8. import 'package:uuid/uuid.dart';
  9. import '/models/conversations.dart';
  10. import '/models/messages.dart';
  11. import '/utils/encryption/aes_helper.dart';
  12. import '/utils/encryption/crypto_utils.dart';
  13. import '/utils/strings.dart';
  14. class ImageMessage extends Message {
  15. File file;
  16. ImageMessage({
  17. id,
  18. symmetricKey,
  19. userSymmetricKey,
  20. senderId,
  21. senderUsername,
  22. associationKey,
  23. createdAt,
  24. failedToSend,
  25. required this.file,
  26. }) : super(
  27. id: id,
  28. symmetricKey: symmetricKey,
  29. userSymmetricKey: userSymmetricKey,
  30. senderId: senderId,
  31. senderUsername: senderUsername,
  32. associationKey: associationKey,
  33. createdAt: createdAt,
  34. failedToSend: failedToSend,
  35. );
  36. static Future<ImageMessage> fromJson(Map<String, dynamic> json, RSAPrivateKey privKey) async {
  37. var userSymmetricKey = CryptoUtils.rsaDecrypt(
  38. base64.decode(json['symmetric_key']),
  39. privKey,
  40. );
  41. var symmetricKey = AesHelper.aesDecrypt(
  42. userSymmetricKey,
  43. base64.decode(json['message_data']['symmetric_key']),
  44. );
  45. var senderId = AesHelper.aesDecrypt(
  46. base64.decode(symmetricKey),
  47. base64.decode(json['message_data']['sender_id']),
  48. );
  49. File file = await getFile(
  50. json['message_data']['attachment']['image_link'],
  51. '${json['id']}',
  52. symmetricKey,
  53. );
  54. return ImageMessage(
  55. id: json['id'],
  56. symmetricKey: symmetricKey,
  57. userSymmetricKey: base64.encode(userSymmetricKey),
  58. senderId: senderId,
  59. senderUsername: 'Unknown',
  60. associationKey: json['association_key'],
  61. createdAt: json['created_at'],
  62. failedToSend: false,
  63. file: file,
  64. );
  65. }
  66. @override
  67. Map<String, dynamic> toMap() {
  68. return {
  69. 'id': id,
  70. 'symmetric_key': symmetricKey,
  71. 'user_symmetric_key': userSymmetricKey,
  72. 'file': file.path,
  73. 'sender_id': senderId,
  74. 'sender_username': senderUsername,
  75. 'association_key': associationKey,
  76. 'created_at': createdAt,
  77. 'failed_to_send': failedToSend ? 1 : 0,
  78. };
  79. }
  80. Future<Map<String, dynamic>> payloadJson(Conversation conversation) async {
  81. final String messageDataId = (const Uuid()).v4();
  82. final symmetricKey = AesHelper.deriveKey(generateRandomString(32));
  83. final userSymmetricKey = AesHelper.deriveKey(generateRandomString(32));
  84. List<Map<String, String>> messages = await super.payloadJsonBase(
  85. symmetricKey,
  86. userSymmetricKey,
  87. conversation,
  88. id,
  89. messageDataId,
  90. );
  91. Map<String, dynamic> messageData = {
  92. 'id': messageDataId,
  93. 'sender_id': AesHelper.aesEncrypt(symmetricKey, Uint8List.fromList(senderId.codeUnits)),
  94. 'symmetric_key': AesHelper.aesEncrypt(
  95. userSymmetricKey,
  96. Uint8List.fromList(base64.encode(symmetricKey).codeUnits),
  97. ),
  98. 'attachment': {
  99. 'data': AesHelper.aesEncrypt(base64.encode(symmetricKey), Uint8List.fromList(file.readAsBytesSync())),
  100. 'mimetype': lookupMimeType(file.path),
  101. 'extension': getExtension(file.path),
  102. }
  103. };
  104. return <String, dynamic>{
  105. 'message_data': messageData,
  106. 'message': messages,
  107. };
  108. }
  109. @override
  110. String getContent() {
  111. return 'Image';
  112. }
  113. @override
  114. String toString() {
  115. return '''
  116. id: $id
  117. file: ${file.path},
  118. senderId: $senderId
  119. senderUsername: $senderUsername
  120. associationKey: $associationKey
  121. createdAt: $createdAt
  122. ''';
  123. }
  124. }