diff --git a/lib/src/double_ratchet/double_ratchet.dart b/lib/src/double_ratchet/double_ratchet.dart index e4f9f22..ca20266 100644 --- a/lib/src/double_ratchet/double_ratchet.dart +++ b/lib/src/double_ratchet/double_ratchet.dart @@ -94,11 +94,20 @@ class OmemoDoubleRatchet { ] } */ - final mkSkipped = >{}; - for (final entry in data['mkskipped']! as List>) { - final key = SkippedKey.fromJson(entry); - mkSkipped[key] = base64.decode(entry['key']! as String); - } + // NOTE: Dart has some issues with just casting a List to List>, as + // such we need to convert the items by hand. + final mkSkipped = Map>.fromEntries( + (data['mkskipped']! as List).map>>( + (entry) { + final map = entry as Map; + final key = SkippedKey.fromJson(map); + return MapEntry( + key, + base64.decode(map['key']! as String), + ); + }, + ), + ); return OmemoDoubleRatchet( OmemoKeyPair.fromBytes( diff --git a/lib/src/omemo/device.dart b/lib/src/omemo/device.dart index 11d6a83..7c26081 100644 --- a/lib/src/omemo/device.dart +++ b/lib/src/omemo/device.dart @@ -49,14 +49,23 @@ class Device { ] } */ - final opks = {}; - for (final opk in data['opks']! as List>) { - opks[opk['id']! as int] = OmemoKeyPair.fromBytes( - base64.decode(opk['public']! as String), - base64.decode(opk['private']! as String), - KeyPairType.x25519, - ); - } + // NOTE: Dart has some issues with just casting a List to List>, as + // such we need to convert the items by hand. + final opks = Map.fromEntries( + (data['opks']! as List).map>( + (opk) { + final map = opk as Map; + return MapEntry( + map['id']! as int, + OmemoKeyPair.fromBytes( + base64.decode(map['public']! as String), + base64.decode(map['private']! as String), + KeyPairType.x25519, + ), + ); + }, + ), + ); return Device( data['jid']! as String, diff --git a/lib/src/omemo/sessionmanager.dart b/lib/src/omemo/sessionmanager.dart index acebb32..7ab9125 100644 --- a/lib/src/omemo/sessionmanager.dart +++ b/lib/src/omemo/sessionmanager.dart @@ -37,10 +37,23 @@ class OmemoSessionManager { /// Deserialise the OmemoSessionManager from JSON data [data] that does not contain /// the ratchet sessions. - factory OmemoSessionManager.fromJsonWithoutSessions(Map data, Map ratchetMap, TrustManager trustManager) { + factory OmemoSessionManager.fromJsonWithoutSessions( + Map data, + Map ratchetMap, + TrustManager trustManager, + ) { + // NOTE: Dart has some issues with just casting a List to List>, as + // such we need to convert the items by hand. return OmemoSessionManager( Device.fromJson(data['device']! as Map), - data['devices']! as Map>, + (data['devices']! as Map).map>( + (key, value) { + return MapEntry( + key, + (value as List).map((i) => i as int).toList(), + ); + } + ), ratchetMap, trustManager, ); diff --git a/test/serialisation_test.dart b/test/serialisation_test.dart index 8244ac7..889f186 100644 --- a/test/serialisation_test.dart +++ b/test/serialisation_test.dart @@ -3,6 +3,10 @@ import 'package:omemo_dart/omemo_dart.dart'; import 'package:omemo_dart/src/trust/always.dart'; import 'package:test/test.dart'; +Map jsonify(Map map) { + return jsonDecode(jsonEncode(map)) as Map; +} + void main() { test('Test serialising and deserialising the Device', () async { // Generate a random session @@ -12,7 +16,7 @@ void main() { opkAmount: 1, ); final oldDevice = await oldSession.getDevice(); - final serialised = await oldDevice.toJson(); + final serialised = jsonify(await oldDevice.toJson()); final newDevice = Device.fromJson(serialised); expect(await oldDevice.equals(newDevice), true); @@ -26,7 +30,7 @@ void main() { opkAmount: 1, ); final oldDevice = await (await oldSession.getDevice()).replaceSignedPrekey(); - final serialised = await oldDevice.toJson(); + final serialised = jsonify(await oldDevice.toJson()); final newDevice = Device.fromJson(serialised); expect(await oldDevice.equals(newDevice), true); @@ -60,7 +64,7 @@ void main() { aliceMessage.encryptedKeys, ); final aliceOld = aliceSession.getRatchet(bobJid, await bobSession.getDeviceId()); - final aliceSerialised = await aliceOld.toJson(); + final aliceSerialised = jsonify(await aliceOld.toJson()); final aliceNew = OmemoDoubleRatchet.fromJson(aliceSerialised); expect(await aliceOld.equals(aliceNew), true); @@ -85,7 +89,7 @@ void main() { ); // Serialise and deserialise - final serialised = await oldSession.toJsonWithoutSessions(); + final serialised = jsonify(await oldSession.toJsonWithoutSessions()); final newSession = OmemoSessionManager.fromJsonWithoutSessions( serialised, // NOTE: At this point, we don't care about this attribute @@ -99,42 +103,6 @@ void main() { expect(await oldSession.getDeviceMap(), await newSession.getDeviceMap()); }); - test('Test serialising and deserialising the BlindTrustBeforeVerificationTrustManager', () async { - // Caroline's BTBV manager - final btbv = MemoryBTBVTrustManager(); - // Example data - const aliceJid = 'alice@some.server'; - const bobJid = 'bob@other.server'; - - // Caroline starts a chat a device from Alice - await btbv.onNewSession(aliceJid, 1); - expect(await btbv.isTrusted(aliceJid, 1), true); - expect(await btbv.isEnabled(aliceJid, 1), true); - - // Caroline meets with Alice and verifies her fingerprint - await btbv.setDeviceTrust(aliceJid, 1, BTBVTrustState.verified); - expect(await btbv.isTrusted(aliceJid, 1), true); - - // Alice adds a new device - await btbv.onNewSession(aliceJid, 2); - expect(await btbv.isTrusted(aliceJid, 2), false); - expect(btbv.getDeviceTrust(aliceJid, 2), BTBVTrustState.notTrusted); - expect(await btbv.isEnabled(aliceJid, 2), false); - - // Caronline starts a chat with Bob but since they live far apart, Caroline cannot - // verify his fingerprint. - await btbv.onNewSession(bobJid, 3); - - // Bob adds a new device - await btbv.onNewSession(bobJid, 4); - expect(await btbv.isTrusted(bobJid, 3), true); - expect(await btbv.isTrusted(bobJid, 4), true); - expect(btbv.getDeviceTrust(bobJid, 3), BTBVTrustState.blindTrust); - expect(btbv.getDeviceTrust(bobJid, 4), BTBVTrustState.blindTrust); - expect(await btbv.isEnabled(bobJid, 3), true); - expect(await btbv.isEnabled(bobJid, 4), true); - }); - test('Test serializing and deserializing RatchetMapKey', () { const test1 = RatchetMapKey('user@example.org', 1234); final result1 = RatchetMapKey.fromJsonKey(test1.toJsonKey()); @@ -160,21 +128,19 @@ void main() { await btbv.onNewSession(bobJid, 3); await btbv.onNewSession(bobJid, 4); - final managerJson = await btbv.toJson(); - final managerString = jsonEncode(managerJson); - final managerPostJson = jsonDecode(managerString) as Map; + final serialized = jsonify(await btbv.toJson()); final deviceList = BlindTrustBeforeVerificationTrustManager.deviceListFromJson( - managerPostJson, + serialized, ); expect(btbv.devices, deviceList); final trustCache = BlindTrustBeforeVerificationTrustManager.trustCacheFromJson( - managerPostJson, + serialized, ); expect(btbv.trustCache, trustCache); final enableCache = BlindTrustBeforeVerificationTrustManager.enableCacheFromJson( - managerPostJson, + serialized, ); expect(btbv.enablementCache, enableCache); });