@@ -75,6 +75,36 @@ async function getOrCreateFederatedRoom({
7575 }
7676}
7777
78+ // get the join rule type from the stripped state stored in the unsigned section of the event
79+ // as per the spec, we must support several types but we only support invite and public for now.
80+ // in the future, we must start looking into 'knock', 'knock_restricted', 'restricted' and 'private'.
81+ function getJoinRuleType ( strippedState : PduForType < 'm.room.join_rules' > [ ] ) : 'p' | 'c' | 'd' {
82+ const joinRulesState = strippedState ?. find ( ( state : PduForType < 'm.room.join_rules' > ) => state . type === 'm.room.join_rules' ) ;
83+
84+ // as per the spec, users need to be invited to join a room, unless the room’s join rules state otherwise.
85+ if ( ! joinRulesState ) {
86+ return 'p' ;
87+ }
88+
89+ const joinRule = joinRulesState ?. content ?. join_rule ;
90+ switch ( joinRule ) {
91+ case 'invite' :
92+ return 'p' ;
93+ case 'public' :
94+ return 'c' ;
95+ case 'knock' :
96+ throw new Error ( `Knock join rule is not supported` ) ;
97+ case 'knock_restricted' :
98+ throw new Error ( `Knock restricted join rule is not supported` ) ;
99+ case 'restricted' :
100+ throw new Error ( `Restricted join rule is not supported` ) ;
101+ case 'private' :
102+ throw new Error ( `Private join rule is not supported` ) ;
103+ default :
104+ throw new Error ( `Unknown join rule type: ${ joinRule } ` ) ;
105+ }
106+ }
107+
78108async function handleInvite ( {
79109 sender : senderId ,
80110 state_key : userId ,
@@ -92,10 +122,13 @@ async function handleInvite({
92122 throw new Error ( `Failed to get or create invitee user: ${ userId } ` ) ;
93123 }
94124
95- // we are not handling public rooms yet - in the future we should use 'c' for public rooms
96- // as well as should rethink the canAccessRoom authorization logic
97- const roomType = content . membership === 'invite' && content ?. is_direct ? 'd' : 'p' ;
98- const strippedState = unsigned ?. invite_room_state ;
125+ const strippedState = unsigned . invite_room_state ;
126+
127+ const joinRuleType = getJoinRuleType ( strippedState ) ;
128+
129+ // DMs do not have a join rule type (they are treated as invite only rooms),
130+ // so we use 'd' for direct messages translation to RC.
131+ const roomType = content ?. is_direct ? 'd' : joinRuleType ;
99132
100133 const roomOriginDomain = senderId . split ( ':' ) ?. pop ( ) ;
101134 if ( ! roomOriginDomain ) {
0 commit comments