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.

145 lines
3.7 KiB

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