diff --git a/lib/matrix_api_lite.dart b/lib/matrix_api_lite.dart index 440ba497..d9d91fa0 100644 --- a/lib/matrix_api_lite.dart +++ b/lib/matrix_api_lite.dart @@ -79,6 +79,7 @@ export 'src/model/auth/authentication_three_pid_creds.dart'; export 'src/model/auth/authentication_token.dart'; export 'src/model/auth/authentication_types.dart'; export 'src/model/auth/authentication_user_identifier.dart'; +export 'src/model/events/forwarded_room_key_content.dart'; export 'src/model/events/room_encrypted_content.dart'; export 'src/model/events/room_encryption_content.dart'; export 'src/model/events/room_key_content.dart'; diff --git a/lib/src/model/events/forwarded_room_key_content.dart b/lib/src/model/events/forwarded_room_key_content.dart new file mode 100644 index 00000000..29cb3221 --- /dev/null +++ b/lib/src/model/events/forwarded_room_key_content.dart @@ -0,0 +1,31 @@ +import '../basic_event.dart'; +import '../../utils/try_get_map_extension.dart'; +import 'room_key_content.dart'; + +extension ForwardedRoomKeyContentBasicEventExtension on BasicEvent { + ForwardedRoomKeyContent get parsedForwardedRoomKeyContent => + ForwardedRoomKeyContent.fromJson(content); +} + +class ForwardedRoomKeyContent extends RoomKeyContent { + String senderKey; + String senderClaimedEd25519Key; + List forwardingCurve25519KeyChain; + ForwardedRoomKeyContent.fromJson(Map json) + : senderKey = json.tryGet('sender_key', ''), + senderClaimedEd25519Key = + json.tryGet('sender_claimed_ed25519_key', ''), + forwardingCurve25519KeyChain = + json.tryGetList('forwarding_curve25519_key_chain', []), + super.fromJson(json); + + @override + Map toJson() { + final data = super.toJson(); + data['sender_key'] = senderKey; + data['sender_claimed_ed25519_key'] = senderClaimedEd25519Key; + data['forwarding_curve25519_key_chain'] = forwardingCurve25519KeyChain; + + return data; + } +} diff --git a/lib/src/model/events/room_key_content.dart b/lib/src/model/events/room_key_content.dart index 8b76dd68..a84a2299 100644 --- a/lib/src/model/events/room_key_content.dart +++ b/lib/src/model/events/room_key_content.dart @@ -11,6 +11,8 @@ class RoomKeyContent { String sessionId; String sessionKey; + RoomKeyContent(); + RoomKeyContent.fromJson(Map json) : algorithm = json.tryGet('algorithm', ''), roomId = json.tryGet('room_id', ''), diff --git a/lib/src/utils/try_get_map_extension.dart b/lib/src/utils/try_get_map_extension.dart index fe8f306c..bc7a926b 100644 --- a/lib/src/utils/try_get_map_extension.dart +++ b/lib/src/utils/try_get_map_extension.dart @@ -15,4 +15,25 @@ extension TryGetMapExtension on Map { } return value; } + + List tryGetList(String key, [List fallbackValue]) { + final value = this[key]; + if (value != null && !(value is List)) { + Logs().w( + 'Expected "${T.runtimeType}" in event content for the key "$key" but got "${value.runtimeType}".'); + return fallbackValue; + } + if (value == null && fallbackValue != null) { + Logs().w( + 'Required field in event content for the key "$key" is null. Set to "$fallbackValue".'); + return fallbackValue; + } + try { + return List.from(value as List); + } catch (_) { + Logs().w( + 'Unable to create List<${T.runtimeType}> in event content for the key "$key'); + return fallbackValue; + } + } } diff --git a/test/event_content_test.dart b/test/event_content_test.dart index 80eb2232..a9ef3e47 100644 --- a/test/event_content_test.dart +++ b/test/event_content_test.dart @@ -18,6 +18,7 @@ import 'package:matrix_api_lite/matrix_api_lite.dart'; import 'package:test/test.dart'; +import 'dart:convert'; void main() { group('Event Content tests', () { @@ -36,6 +37,7 @@ void main() { 'type': 'm.room.encryption', 'unsigned': {'age': 1234} }; + json = jsonDecode(jsonEncode(json)); expect(MatrixEvent.fromJson(json).parsedRoomEncryptionContent.toJson(), json['content']); }); @@ -55,6 +57,7 @@ void main() { 'type': 'm.room.encrypted', 'unsigned': {'age': 1234} }; + json = jsonDecode(jsonEncode(json)); expect(MatrixEvent.fromJson(json).parsedRoomEncryptedContent.toJson(), json['content']); json = { @@ -75,6 +78,7 @@ void main() { 'type': 'm.room.encrypted', 'unsigned': {'age': 1234} }; + json = jsonDecode(jsonEncode(json)); expect(MatrixEvent.fromJson(json).parsedRoomEncryptedContent.toJson(), json['content']); }); @@ -88,6 +92,7 @@ void main() { }, 'type': 'm.room_key' }; + json = jsonDecode(jsonEncode(json)); expect(BasicEvent.fromJson(json).parsedRoomKeyContent.toJson(), json['content']); }); @@ -100,6 +105,7 @@ void main() { }, 'type': 'm.room_key_request' }; + json = jsonDecode(jsonEncode(json)); expect(BasicEvent.fromJson(json).parsedRoomKeyRequestContent.toJson(), json['content']); json = { @@ -116,8 +122,29 @@ void main() { }, 'type': 'm.room_key_request' }; + json = jsonDecode(jsonEncode(json)); expect(BasicEvent.fromJson(json).parsedRoomKeyRequestContent.toJson(), json['content']); }); + test('Forwarded Room Key Content', () { + var json = { + 'content': { + 'algorithm': 'm.megolm.v1.aes-sha2', + 'forwarding_curve25519_key_chain': [ + 'hPQNcabIABgGnx3/ACv/jmMmiQHoeFfuLB17tzWp6Hw' + ], + 'room_id': '!Cuyf34gef24t:localhost', + 'sender_claimed_ed25519_key': + 'aj40p+aw64yPIdsxoog8jhPu9i7l7NcFRecuOQblE3Y', + 'sender_key': 'RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU', + 'session_id': 'X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ', + 'session_key': 'AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8Llf...' + }, + 'type': 'm.forwarded_room_key' + }; + json = jsonDecode(jsonEncode(json)); + expect(BasicEvent.fromJson(json).parsedForwardedRoomKeyContent.toJson(), + json['content']); + }); }); }