Fix issue where a member is forced to leave a room when the invite is marked deleted (#2839)
Proposed fix for issue: https://github.com/matrix-org/dendrite/issues/2838 Suppose bob received invites to spaceA and spaceB. When Bob joins spaceA, we add an OutputEvent event to retire the invite. This sets the invite to "deleted" in the database. This makes sense. The bug is in stream_invites.go. Triggered when bob received a new invite for spaceB, and does a client sync. In the block (line 76) `for roomID := range retiredInvites if _, ok := req.Response.Rooms.Invite[roomID]; ok { continue } if _, ok := req.Response.Rooms.Join[roomID]; ok { continue } ... ` Bob is not in either maps even though he had just accepted the invite for spaceA. Consequently, the spaceA invite is treated as a retired invite, and a membership Leave event is generated. What bob sees is that after accepting the invite to spaceB, he lose access to spaceA. ### Pull Request Checklist <!-- Please read https://matrix-org.github.io/dendrite/development/contributing before submitting your pull request --> * [ ] I have added tests for PR _or_ I have justified why this PR doesn't need tests. * [x ] Pull request includes a [sign off below using a legally identifiable name](https://matrix-org.github.io/dendrite/development/contributing#sign-off) _or_ I have already signed off privately Signed-off-by: `Tak Wai Wong <tak@hntlabs.com>` Co-authored-by: Neil Alexander <neilalexander@users.noreply.github.com>
This commit is contained in:
parent
3db9e98456
commit
75a508cc27
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -74,12 +75,14 @@ func (p *InviteStreamProvider) IncrementalSync(
|
||||||
return to
|
return to
|
||||||
}
|
}
|
||||||
for roomID := range retiredInvites {
|
for roomID := range retiredInvites {
|
||||||
if _, ok := req.Response.Rooms.Invite[roomID]; ok {
|
membership, _, err := snapshot.SelectMembershipForUser(ctx, roomID, req.Device.UserID, math.MaxInt64)
|
||||||
continue
|
// Skip if the user is an existing member of the room.
|
||||||
}
|
// Otherwise, the NewLeaveResponse will eject the user from the room unintentionally
|
||||||
if _, ok := req.Response.Rooms.Join[roomID]; ok {
|
if membership == gomatrixserverlib.Join ||
|
||||||
|
err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
lr := types.NewLeaveResponse()
|
lr := types.NewLeaveResponse()
|
||||||
h := sha256.Sum256(append([]byte(roomID), []byte(strconv.FormatInt(int64(to), 10))...))
|
h := sha256.Sum256(append([]byte(roomID), []byte(strconv.FormatInt(int64(to), 10))...))
|
||||||
lr.Timeline.Events = append(lr.Timeline.Events, gomatrixserverlib.ClientEvent{
|
lr.Timeline.Events = append(lr.Timeline.Events, gomatrixserverlib.ClientEvent{
|
||||||
|
@ -93,7 +96,6 @@ func (p *InviteStreamProvider) IncrementalSync(
|
||||||
Content: gomatrixserverlib.RawJSON(`{"membership":"leave"}`),
|
Content: gomatrixserverlib.RawJSON(`{"membership":"leave"}`),
|
||||||
})
|
})
|
||||||
req.Response.Rooms.Leave[roomID] = lr
|
req.Response.Rooms.Leave[roomID] = lr
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return maxID
|
return maxID
|
||||||
|
|
Loading…
Reference in a new issue