@@ -187,6 +187,13 @@ pub struct InboundGroupSession {
187187 /// key.
188188 pub sender_data : SenderData ,
189189
190+ /// If this session was shared-on-invite as part of an [MSC4268] key bundle,
191+ /// information about the user who forwarded us the session information.
192+ /// This is distinct from [`InboundGroupSession::sender_data`].
193+ ///
194+ /// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268
195+ pub forwarder_data : Option < SenderData > ,
196+
190197 /// The Room this GroupSession belongs to
191198 pub room_id : OwnedRoomId ,
192199
@@ -240,6 +247,10 @@ impl InboundGroupSession {
240247 /// * `sender_data` - Information about the sender of the to-device message
241248 /// that established this session.
242249 ///
250+ /// * `forwarder_data` - If present, indicates this session was received via
251+ /// an [MSC4268] room key bundle, and provides information about the
252+ /// forwarder of this bundle.
253+ ///
243254 /// * `encryption_algorithm` - The [`EventEncryptionAlgorithm`] that should
244255 /// be used when messages are being decrypted. The method will return an
245256 /// [`SessionCreationError::Algorithm`] error if an algorithm we do not
@@ -256,13 +267,15 @@ impl InboundGroupSession {
256267 /// history visibility of the room.
257268 ///
258269 /// [MSC3061]: https://github.com/matrix-org/matrix-spec-proposals/pull/3061
270+ /// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268
259271 #[ allow( clippy:: too_many_arguments) ]
260272 pub fn new (
261273 sender_key : Curve25519PublicKey ,
262274 signing_key : Ed25519PublicKey ,
263275 room_id : & RoomId ,
264276 session_key : & SessionKey ,
265277 sender_data : SenderData ,
278+ forwarder_data : Option < SenderData > ,
266279 encryption_algorithm : EventEncryptionAlgorithm ,
267280 history_visibility : Option < HistoryVisibility > ,
268281 shared_history : bool ,
@@ -286,6 +299,7 @@ impl InboundGroupSession {
286299 signing_keys : keys. into ( ) ,
287300 } ,
288301 sender_data,
302+ forwarder_data,
289303 room_id : room_id. into ( ) ,
290304 imported : false ,
291305 algorithm : encryption_algorithm. into ( ) ,
@@ -325,6 +339,7 @@ impl InboundGroupSession {
325339 room_id,
326340 session_key,
327341 SenderData :: unknown ( ) ,
342+ None ,
328343 EventEncryptionAlgorithm :: MegolmV1AesSha2 ,
329344 None ,
330345 * shared_history,
@@ -380,6 +395,7 @@ impl InboundGroupSession {
380395 sender_key : self . creator_info . curve25519_key ,
381396 signing_key : ( * self . creator_info . signing_keys ) . clone ( ) ,
382397 sender_data : self . sender_data . clone ( ) ,
398+ forwarder_data : self . forwarder_data . clone ( ) ,
383399 room_id : self . room_id ( ) . to_owned ( ) ,
384400 imported : self . imported ,
385401 backed_up : self . backed_up ( ) ,
@@ -459,6 +475,7 @@ impl InboundGroupSession {
459475 sender_key,
460476 signing_key,
461477 sender_data,
478+ forwarder_data,
462479 room_id,
463480 imported,
464481 backed_up,
@@ -479,6 +496,7 @@ impl InboundGroupSession {
479496 signing_keys : signing_key. into ( ) ,
480497 } ,
481498 sender_data,
499+ forwarder_data,
482500 history_visibility : history_visibility. into ( ) ,
483501 first_known_index,
484502 room_id,
@@ -691,6 +709,9 @@ pub struct PickledInboundGroupSession {
691709 /// Information on the device/sender who sent us this session
692710 #[ serde( default ) ]
693711 pub sender_data : SenderData ,
712+ /// Information on the device/sender who forwarded us this session
713+ #[ serde( default ) ]
714+ pub forwarder_data : Option < SenderData > ,
694715 /// The id of the room that the session is used in.
695716 pub room_id : OwnedRoomId ,
696717 /// Flag remembering if the session was directly sent to us by the sender
@@ -717,18 +738,41 @@ fn default_algorithm() -> EventEncryptionAlgorithm {
717738 EventEncryptionAlgorithm :: MegolmV1AesSha2
718739}
719740
720- impl TryFrom < & HistoricRoomKey > for InboundGroupSession {
721- type Error = SessionCreationError ;
722-
723- fn try_from ( key : & HistoricRoomKey ) -> Result < Self , Self :: Error > {
741+ impl HistoricRoomKey {
742+ /// Converts a `HistoricRoomKey` into an `InboundGroupSession`.
743+ ///
744+ /// This method takes the current `HistoricRoomKey` instance and attempts to
745+ /// create an `InboundGroupSession` from it. The `forwarder_data` parameter
746+ /// provides information about the user or device that forwarded the session
747+ /// information. This is normally distinct from the original sender of the
748+ /// session.
749+ ///
750+ /// # Arguments
751+ ///
752+ /// * `forwarder_data` - A reference to a `SenderData` object containing
753+ /// information about the forwarder of the session.
754+ ///
755+ /// # Returns
756+ ///
757+ /// Returns a `Result` containing the newly created `InboundGroupSession` on
758+ /// success, or a `SessionCreationError` if the conversion fails.
759+ ///
760+ /// # Errors
761+ ///
762+ /// This method will return a `SessionCreationError` if the session
763+ /// configuration for the given algorithm cannot be determined.
764+ pub fn try_into_inbound_group_session (
765+ & self ,
766+ forwarder_data : & SenderData ,
767+ ) -> Result < InboundGroupSession , SessionCreationError > {
724768 let HistoricRoomKey {
725769 algorithm,
726770 room_id,
727771 sender_key,
728772 session_id,
729773 session_key,
730774 sender_claimed_keys,
731- } = key ;
775+ } = self ;
732776
733777 let config = OutboundGroupSession :: session_config ( algorithm) ?;
734778 let session = InnerSession :: import ( session_key, config) ;
@@ -744,6 +788,7 @@ impl TryFrom<&HistoricRoomKey> for InboundGroupSession {
744788 // TODO: How do we remember that this is a historic room key and events decrypted using
745789 // this room key should always show some form of warning.
746790 sender_data : SenderData :: default ( ) ,
791+ forwarder_data : Some ( forwarder_data. clone ( ) ) ,
747792 history_visibility : None . into ( ) ,
748793 first_known_index,
749794 room_id : room_id. to_owned ( ) ,
@@ -784,6 +829,7 @@ impl TryFrom<&ExportedRoomKey> for InboundGroupSession {
784829 // TODO: In future, exported keys should contain sender data that we can use here.
785830 // See https://github.com/matrix-org/matrix-rust-sdk/issues/3548
786831 sender_data : SenderData :: default ( ) ,
832+ forwarder_data : None ,
787833 history_visibility : None . into ( ) ,
788834 first_known_index,
789835 room_id : room_id. to_owned ( ) ,
@@ -815,6 +861,7 @@ impl From<&ForwardedMegolmV1AesSha2Content> for InboundGroupSession {
815861 // In future, exported keys should contain sender data that we can use here.
816862 // See https://github.com/matrix-org/matrix-rust-sdk/issues/3548
817863 sender_data : SenderData :: default ( ) ,
864+ forwarder_data : None ,
818865 history_visibility : None . into ( ) ,
819866 first_known_index,
820867 room_id : value. room_id . to_owned ( ) ,
@@ -842,6 +889,7 @@ impl From<&ForwardedMegolmV2AesSha2Content> for InboundGroupSession {
842889 // In future, exported keys should contain sender data that we can use here.
843890 // See https://github.com/matrix-org/matrix-rust-sdk/issues/3548
844891 sender_data : SenderData :: default ( ) ,
892+ forwarder_data : None ,
845893 history_visibility : None . into ( ) ,
846894 first_known_index,
847895 room_id : value. room_id . to_owned ( ) ,
@@ -871,7 +919,7 @@ impl TryFrom<&DecryptedForwardedRoomKeyEvent> for InboundGroupSession {
871919#[ cfg( test) ]
872920mod tests {
873921 use assert_matches2:: assert_let;
874- use insta:: assert_json_snapshot;
922+ use insta:: { assert_json_snapshot, with_settings } ;
875923 use matrix_sdk_test:: async_test;
876924 use ruma:: {
877925 DeviceId , UserId , device_id, events:: room:: history_visibility:: HistoryVisibility ,
@@ -906,11 +954,17 @@ mod tests {
906954
907955 let pickle = session. pickle ( ) . await ;
908956
909- assert_json_snapshot ! ( pickle, {
910- ".pickle.initial_ratchet.inner" => "[ratchet]" ,
911- ".pickle.signing_key" => "[signing_key]" ,
912- ".sender_key" => "[sender_key]" ,
913- ".signing_key.ed25519" => "[ed25519_key]" ,
957+ with_settings ! ( { prepend_module_to_snapshot => false } , {
958+ assert_json_snapshot!(
959+ "InboundGroupSession__test_pickle_snapshot__regression" ,
960+ pickle,
961+ {
962+ ".pickle.initial_ratchet.inner" => "[ratchet]" ,
963+ ".pickle.signing_key" => "[signing_key]" ,
964+ ".sender_key" => "[sender_key]" ,
965+ ".signing_key.ed25519" => "[ed25519_key]" ,
966+ }
967+ ) ;
914968 } ) ;
915969 }
916970
@@ -982,6 +1036,7 @@ mod tests {
9821036 room_id ! ( "!test:localhost" ) ,
9831037 & create_session_key ( ) ,
9841038 SenderData :: unknown ( ) ,
1039+ None ,
9851040 EventEncryptionAlgorithm :: MegolmV1AesSha2 ,
9861041 Some ( HistoryVisibility :: Shared ) ,
9871042 false ,
@@ -1028,6 +1083,7 @@ mod tests {
10281083 "legacy_session" : false
10291084 }
10301085 } ,
1086+ "forwarder_data" : null,
10311087 "room_id" : "!test:localhost" ,
10321088 "imported" : false ,
10331089 "backed_up" : false ,
0 commit comments