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.

120 lines
3.3 KiB

  1. import 'dart:convert';
  2. import 'package:http/http.dart' as http;
  3. import 'package:sqflite/sqflite.dart';
  4. import 'package:uuid/uuid.dart';
  5. import '/models/conversation_users.dart';
  6. import '/models/conversations.dart';
  7. import '/models/messages.dart';
  8. import '/models/my_profile.dart';
  9. import '/utils/storage/database.dart';
  10. import '/utils/storage/session_cookie.dart';
  11. Future<void> sendMessage(Conversation conversation, String data) async {
  12. MyProfile profile = await MyProfile.getProfile();
  13. var uuid = const Uuid();
  14. final String messageId = uuid.v4();
  15. ConversationUser currentUser = await getConversationUser(conversation, profile.id);
  16. Message message = Message(
  17. id: messageId,
  18. symmetricKey: '',
  19. userSymmetricKey: '',
  20. senderId: currentUser.userId,
  21. senderUsername: profile.username,
  22. data: data,
  23. associationKey: currentUser.associationKey,
  24. createdAt: DateTime.now().toIso8601String(),
  25. failedToSend: false,
  26. );
  27. final db = await getDatabaseConnection();
  28. await db.insert(
  29. 'messages',
  30. message.toMap(),
  31. conflictAlgorithm: ConflictAlgorithm.replace,
  32. );
  33. String sessionCookie = await getSessionCookie();
  34. message.payloadJson(conversation, messageId)
  35. .then((messageJson) async {
  36. return http.post(
  37. await MyProfile.getServerUrl('api/v1/auth/message'),
  38. headers: <String, String>{
  39. 'Content-Type': 'application/json; charset=UTF-8',
  40. 'cookie': sessionCookie,
  41. },
  42. body: messageJson,
  43. );
  44. })
  45. .then((resp) {
  46. if (resp.statusCode != 200) {
  47. throw Exception('Unable to send message');
  48. }
  49. })
  50. .catchError((exception) {
  51. message.failedToSend = true;
  52. db.update(
  53. 'messages',
  54. message.toMap(),
  55. where: 'id = ?',
  56. whereArgs: [message.id],
  57. );
  58. throw exception;
  59. });
  60. }
  61. Future<void> updateMessageThread(Conversation conversation, {MyProfile? profile}) async {
  62. profile ??= await MyProfile.getProfile();
  63. ConversationUser currentUser = await getConversationUser(conversation, profile.id);
  64. var resp = await http.get(
  65. await MyProfile.getServerUrl('api/v1/auth/messages/${currentUser.associationKey}'),
  66. headers: {
  67. 'cookie': await getSessionCookie(),
  68. }
  69. );
  70. if (resp.statusCode != 200) {
  71. throw Exception(resp.body);
  72. }
  73. List<dynamic> messageThreadJson = jsonDecode(resp.body);
  74. final db = await getDatabaseConnection();
  75. for (var i = 0; i < messageThreadJson.length; i++) {
  76. Message message = Message.fromJson(
  77. messageThreadJson[i] as Map<String, dynamic>,
  78. profile.privateKey!,
  79. );
  80. ConversationUser messageUser = await getConversationUser(conversation, message.senderId);
  81. message.senderUsername = messageUser.username;
  82. await db.insert(
  83. 'messages',
  84. message.toMap(),
  85. conflictAlgorithm: ConflictAlgorithm.replace,
  86. );
  87. }
  88. }
  89. Future<void> updateMessageThreads({List<Conversation>? conversations}) async {
  90. // try {
  91. MyProfile profile = await MyProfile.getProfile();
  92. conversations ??= await getConversations();
  93. for (var i = 0; i < conversations.length; i++) {
  94. await updateMessageThread(conversations[i], profile: profile);
  95. }
  96. // } catch(SocketException) {
  97. // return;
  98. // }
  99. }