import 'dart:convert'; import 'dart:typed_data'; import 'package:Capsule/utils/encryption/aes_helper.dart'; import 'package:Capsule/utils/encryption/crypto_utils.dart'; import 'package:pointycastle/impl.dart'; import '/models/conversations.dart'; import '/utils/storage/database.dart'; Future getConversationUser(Conversation conversation, String userId) async { final db = await getDatabaseConnection(); final List> maps = await db.query( 'conversation_users', where: 'conversation_id = ? AND user_id = ?', whereArgs: [ conversation.id, userId ], ); if (maps.length != 1) { throw ArgumentError('Invalid conversation_id or username'); } return ConversationUser( id: maps[0]['id'], userId: maps[0]['user_id'], conversationId: maps[0]['conversation_id'], username: maps[0]['username'], associationKey: maps[0]['association_key'], publicKey: CryptoUtils.rsaPublicKeyFromPem(maps[0]['asymmetric_public_key']), admin: maps[0]['admin'] == 1, ); } // A method that retrieves all the dogs from the dogs table. Future> getConversationUsers(Conversation conversation) async { final db = await getDatabaseConnection(); final List> maps = await db.query( 'conversation_users', where: 'conversation_id = ?', whereArgs: [ conversation.id ], orderBy: 'username', ); List conversationUsers = List.generate(maps.length, (i) { return ConversationUser( id: maps[i]['id'], userId: maps[i]['user_id'], conversationId: maps[i]['conversation_id'], username: maps[i]['username'], associationKey: maps[i]['association_key'], publicKey: CryptoUtils.rsaPublicKeyFromPem(maps[i]['asymmetric_public_key']), admin: maps[i]['admin'] == 1, ); }); int index = 0; List finalConversationUsers = []; for (ConversationUser conversationUser in conversationUsers) { if (!conversationUser.admin) { finalConversationUsers.add(conversationUser); continue; } finalConversationUsers.insert(index, conversationUser); index++; } return finalConversationUsers; } Future>> getEncryptedConversationUsers(Conversation conversation, Uint8List symKey) async { final db = await getDatabaseConnection(); final List> maps = await db.query( 'conversation_users', where: 'conversation_id = ?', whereArgs: [conversation.id], orderBy: 'username', ); List> conversationUsers = List.generate(maps.length, (i) { return { 'id': maps[i]['id'], 'conversation_id': maps[i]['conversation_id'], 'user_id': AesHelper.aesEncrypt(symKey, Uint8List.fromList(maps[i]['user_id'].codeUnits)), 'username': AesHelper.aesEncrypt(symKey, Uint8List.fromList(maps[i]['username'].codeUnits)), 'association_key': AesHelper.aesEncrypt(symKey, Uint8List.fromList(maps[i]['association_key'].codeUnits)), 'public_key': AesHelper.aesEncrypt(symKey, Uint8List.fromList(maps[i]['asymmetric_public_key'].codeUnits)), 'admin': AesHelper.aesEncrypt(symKey, Uint8List.fromList((maps[i]['admin'] == 1 ? 'true' : 'false').codeUnits)), }; }); return conversationUsers; } class ConversationUser{ String id; String userId; String conversationId; String username; String associationKey; RSAPublicKey publicKey; bool admin; ConversationUser({ required this.id, required this.userId, required this.conversationId, required this.username, required this.associationKey, required this.publicKey, required this.admin, }); factory ConversationUser.fromJson(Map json, Uint8List symmetricKey) { String userId = AesHelper.aesDecrypt( symmetricKey, base64.decode(json['user_id']), ); String username = AesHelper.aesDecrypt( symmetricKey, base64.decode(json['username']), ); String associationKey = AesHelper.aesDecrypt( symmetricKey, base64.decode(json['association_key']), ); String admin = AesHelper.aesDecrypt( symmetricKey, base64.decode(json['admin']), ); String publicKeyString = AesHelper.aesDecrypt( symmetricKey, base64.decode(json['public_key']), ); RSAPublicKey publicKey = CryptoUtils.rsaPublicKeyFromPem(publicKeyString); return ConversationUser( id: json['id'], conversationId: json['conversation_detail_id'], userId: userId, username: username, associationKey: associationKey, publicKey: publicKey, admin: admin == 'true', ); } Map toJson() { return { 'id': id, 'user_id': userId, 'username': username, 'association_key': associationKey, 'asymmetric_public_key': publicKeyPem(), 'admin': admin ? 'true' : 'false', }; } Map toMap() { return { 'id': id, 'user_id': userId, 'conversation_id': conversationId, 'username': username, 'association_key': associationKey, 'asymmetric_public_key': publicKeyPem(), 'admin': admin ? 1 : 0, }; } String publicKeyPem() { return CryptoUtils.encodeRSAPublicKeyToPem(publicKey); } }