@@ -883,6 +883,7 @@ func (e *eventAllower) commonChecks(event *Event) error {
883883// A membershipAllower has the information needed to authenticate a m.room.member event
884884type membershipAllower struct {
885885 * allowerContext
886+ roomVersion RoomVersion
886887 // The m.room.third_party_invite content referenced by this event.
887888 thirdPartyInvite ThirdPartyInviteContent
888889 // The user ID of the user whose membership is changing.
@@ -901,6 +902,7 @@ type membershipAllower struct {
901902// from the auth events.
902903func (a * allowerContext ) newMembershipAllower (authEvents AuthEventProvider , event * Event ) (m membershipAllower , err error ) { // nolint: gocyclo
903904 m .allowerContext = a
905+ m .roomVersion = event .roomVersion
904906 stateKey := event .StateKey ()
905907 if stateKey == nil {
906908 err = errorf ("m.room.member must be a state event" )
@@ -1016,18 +1018,18 @@ func (m *membershipAllower) membershipAllowedSelf() error { // nolint: gocyclo
10161018 return nil
10171019 }
10181020 if m .newMember .Membership == Knock {
1021+ if m .joinRule .JoinRule != Knock {
1022+ return m .membershipFailed ()
1023+ }
10191024 // A user that is not in the room is allowed to knock if the join
10201025 // rules are "knock" and they are not already joined to, invited to
10211026 // or banned from the room.
10221027 // Spec: https://spec.matrix.org/unstable/rooms/v7/
1023- if supported , err := m .create . RoomVersion .AllowKnockingInEventAuth (); err != nil {
1024- return err
1028+ if supported , err := m .roomVersion .AllowKnockingInEventAuth (); err != nil {
1029+ return fmt . Errorf ( "m.roomVersion.AllowKnockingInEventAuth: %w" , err )
10251030 } else if ! supported {
10261031 return m .membershipFailed ()
10271032 }
1028- if m .joinRule .JoinRule != Knock {
1029- return m .membershipFailed ()
1030- }
10311033 switch m .oldMember .Membership {
10321034 case Join , Invite , Ban :
10331035 // The user is already joined, invited or banned, therefore they
@@ -1052,6 +1054,10 @@ func (m *membershipAllower) membershipAllowedSelf() error { // nolint: gocyclo
10521054 if m .oldMember .Membership == Invite && m .joinRule .JoinRule == Invite {
10531055 return nil
10541056 }
1057+ // An invited user is allowed to join if the join rules are "knock"
1058+ if m .oldMember .Membership == Invite && m .joinRule .JoinRule == Knock {
1059+ return nil
1060+ }
10551061 // A joined user is allowed to update their join.
10561062 if m .oldMember .Membership == Join {
10571063 return nil
@@ -1115,6 +1121,15 @@ func (m *membershipAllower) membershipAllowedOther() error { // nolint: gocyclo
11151121 if m .oldMember .Membership == Invite && senderLevel >= m .powerLevels .Invite {
11161122 return nil
11171123 }
1124+ // A user can invite in response to a knock.
1125+ if m .joinRule .JoinRule == Knock && m .oldMember .Membership == Knock && senderLevel >= m .powerLevels .Invite {
1126+ if supported , err := m .roomVersion .AllowKnockingInEventAuth (); err != nil {
1127+ return fmt .Errorf ("m.roomVersion.AllowKnockingInEventAuth: %w" , err )
1128+ } else if ! supported {
1129+ return m .membershipFailed ()
1130+ }
1131+ return nil
1132+ }
11181133 }
11191134
11201135 return m .membershipFailed ()
0 commit comments