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.

124 lines
3.4 KiB

  1. import 'dart:convert';
  2. import 'dart:typed_data';
  3. import 'package:Envelope/models/conversation_users.dart';
  4. import 'package:Envelope/models/my_profile.dart';
  5. import 'package:Envelope/models/text_messages.dart';
  6. import 'package:Envelope/utils/encryption/aes_helper.dart';
  7. import 'package:Envelope/utils/encryption/crypto_utils.dart';
  8. import 'package:Envelope/utils/strings.dart';
  9. import 'package:pointycastle/pointycastle.dart';
  10. import '/models/conversations.dart';
  11. import '/utils/storage/database.dart';
  12. const messageTypeReceiver = 'receiver';
  13. const messageTypeSender = 'sender';
  14. Future<List<Message>> getMessagesForThread(Conversation conversation) async {
  15. final db = await getDatabaseConnection();
  16. final List<Map<String, dynamic>> maps = await db.rawQuery(
  17. '''
  18. SELECT * FROM messages WHERE association_key IN (
  19. SELECT association_key FROM conversation_users WHERE conversation_id = ?
  20. )
  21. ORDER BY created_at DESC;
  22. ''',
  23. [conversation.id]
  24. );
  25. return List.generate(maps.length, (i) {
  26. return TextMessage(
  27. id: maps[i]['id'],
  28. symmetricKey: maps[i]['symmetric_key'],
  29. userSymmetricKey: maps[i]['user_symmetric_key'],
  30. text: maps[i]['data'],
  31. senderId: maps[i]['sender_id'],
  32. senderUsername: maps[i]['sender_username'],
  33. associationKey: maps[i]['association_key'],
  34. createdAt: maps[i]['created_at'],
  35. failedToSend: maps[i]['failed_to_send'] == 1,
  36. );
  37. });
  38. }
  39. class Message {
  40. String id;
  41. String symmetricKey;
  42. String userSymmetricKey;
  43. String senderId;
  44. String senderUsername;
  45. String associationKey;
  46. String createdAt;
  47. bool failedToSend;
  48. Message({
  49. required this.id,
  50. required this.symmetricKey,
  51. required this.userSymmetricKey,
  52. required this.senderId,
  53. required this.senderUsername,
  54. required this.associationKey,
  55. required this.createdAt,
  56. required this.failedToSend,
  57. });
  58. Future<List<Map<String, String>>> payloadJsonBase(
  59. Uint8List symmetricKey,
  60. Conversation conversation,
  61. String messageId,
  62. String messageDataId,
  63. ) async {
  64. MyProfile profile = await MyProfile.getProfile();
  65. if (profile.publicKey == null) {
  66. throw Exception('Could not get profile.publicKey');
  67. }
  68. RSAPublicKey publicKey = profile.publicKey!;
  69. final userSymmetricKey = AesHelper.deriveKey(generateRandomString(32));
  70. List<Map<String, String>> messages = [];
  71. List<ConversationUser> conversationUsers = await getConversationUsers(conversation);
  72. for (var i = 0; i < conversationUsers.length; i++) {
  73. ConversationUser user = conversationUsers[i];
  74. if (profile.id == user.userId) {
  75. id = user.id;
  76. messages.add({
  77. 'id': messageId,
  78. 'message_data_id': messageDataId,
  79. 'symmetric_key': base64.encode(CryptoUtils.rsaEncrypt(
  80. userSymmetricKey,
  81. publicKey,
  82. )),
  83. 'association_key': user.associationKey,
  84. });
  85. continue;
  86. }
  87. ConversationUser conversationUser = await getConversationUser(conversation, user.userId);
  88. RSAPublicKey friendPublicKey = conversationUser.publicKey;
  89. messages.add({
  90. 'message_data_id': messageDataId,
  91. 'symmetric_key': base64.encode(CryptoUtils.rsaEncrypt(
  92. userSymmetricKey,
  93. friendPublicKey,
  94. )),
  95. 'association_key': user.associationKey,
  96. });
  97. }
  98. return messages;
  99. }
  100. String getContent() {
  101. return '';
  102. }
  103. }