import 'dart:convert'; import 'package:uuid/uuid.dart'; import 'package:Envelope/models/conversation_users.dart'; import 'package:intl/intl.dart'; import 'package:http/http.dart' as http; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:pointycastle/export.dart'; import 'package:sqflite/sqflite.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '/utils/storage/session_cookie.dart'; import '/utils/storage/encryption_keys.dart'; import '/utils/storage/database.dart'; import '/models/conversations.dart'; import '/models/messages.dart'; Future updateMessageThread(Conversation conversation, {RSAPrivateKey? privKey}) async { privKey ??= await getPrivateKey(); final preferences = await SharedPreferences.getInstance(); String username = preferences.getString('username')!; ConversationUser currentUser = await getConversationUserByUsername(conversation, username); var resp = await http.get( Uri.parse('${dotenv.env["SERVER_URL"]}api/v1/auth/messages/${currentUser.associationKey}'), headers: { 'cookie': await getSessionCookie(), } ); if (resp.statusCode != 200) { throw Exception(resp.body); } List messageThreadJson = jsonDecode(resp.body); final db = await getDatabaseConnection(); for (var i = 0; i < messageThreadJson.length; i++) { Message message = Message.fromJson( messageThreadJson[i] as Map, privKey, ); ConversationUser messageUser = await getConversationUserById(conversation, message.senderId); message.senderUsername = messageUser.username; await db.insert( 'messages', message.toMap(), conflictAlgorithm: ConflictAlgorithm.replace, ); } } Future updateMessageThreads({List? conversations}) async { try { RSAPrivateKey privKey = await getPrivateKey(); conversations ??= await getConversations(); for (var i = 0; i < conversations.length; i++) { await updateMessageThread(conversations[i], privKey: privKey); } } catch(SocketException) { return; } } Future sendMessage(Conversation conversation, String data) async { final preferences = await SharedPreferences.getInstance(); final userId = preferences.getString('userId'); final username = preferences.getString('username'); if (userId == null || username == null) { throw Exception('Invalid user id'); } var uuid = const Uuid(); final String messageDataId = uuid.v4(); ConversationUser currentUser = await getConversationUserByUsername(conversation, username); Message message = Message( id: messageDataId, symmetricKey: '', userSymmetricKey: '', senderId: userId, senderUsername: username, data: data, associationKey: currentUser.associationKey, createdAt: DateTime.now().toIso8601String(), failedToSend: false, ); final db = await getDatabaseConnection(); await db.insert( 'messages', message.toMap(), conflictAlgorithm: ConflictAlgorithm.replace, ); String sessionCookie = await getSessionCookie(); message.toJson(conversation, messageDataId) .then((messageJson) { return http.post( Uri.parse('${dotenv.env["SERVER_URL"]}api/v1/auth/message'), headers: { 'Content-Type': 'application/json; charset=UTF-8', 'cookie': sessionCookie, }, body: messageJson, ); }) .then((resp) { if (resp.statusCode != 200) { throw Exception('Unable to send message'); } }) .catchError((exception) { message.failedToSend = true; db.update( 'messages', message.toMap(), where: 'id = ?', whereArgs: [message.id], ); }); }