From 0cac2af1db5c239e898d953d097b508a54e65725 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 27 Oct 2023 15:20:08 -0400 Subject: [PATCH] fix(community): getting kicked out of a community should still spectate (#4217) Fixes https://github.com/status-im/status-desktop/issues/12558 When getting kicked out of a community, before we used to leave the community completely, but just keep the filters on. That created a problem when reopening the app, because the community disappeared and could even create a problem in desktop where it tried to open the last opened community but it's no longer there. The fix now is that when getting kicked out, we instead just remove ourselves from the community and set Joined to false, but we keep the community spectated. --- protocol/communities/community_changes.go | 5 ++-- protocol/communities/manager.go | 25 +++++++++++++++-- protocol/messenger_communities.go | 34 +++++++++++++---------- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/protocol/communities/community_changes.go b/protocol/communities/community_changes.go index 6409d001f..0cd40dde2 100644 --- a/protocol/communities/community_changes.go +++ b/protocol/communities/community_changes.go @@ -42,9 +42,8 @@ type CommunityChanges struct { // automatically ShouldMemberJoin bool `json:"memberAdded"` - // ShouldMemberJoin indicates whether the user should leave this community - // automatically - ShouldMemberLeave bool `json:"memberRemoved"` + // MemberKicked indicates whether the user has been kicked out + MemberKicked bool `json:"memberRemoved"` } func EmptyCommunityChanges() *CommunityChanges { diff --git a/protocol/communities/manager.go b/protocol/communities/manager.go index eff5597c7..697967e67 100644 --- a/protocol/communities/manager.go +++ b/protocol/communities/manager.go @@ -1684,8 +1684,8 @@ func (m *Manager) handleCommunityDescriptionMessageCommon(community *Community, } if changes.HasMemberLeft(pkString) { - // If we joined previously the community, we should leave it - changes.ShouldMemberLeave = community.Joined() + // If we joined previously the community, that means we have been kicked + changes.MemberKicked = community.Joined() } } @@ -2964,6 +2964,27 @@ func (m *Manager) LeaveCommunity(id types.HexBytes) (*Community, error) { return community, nil } +// Same as LeaveCommunity, but we want to stay spectating +func (m *Manager) KickedOutOfCommunity(id types.HexBytes) (*Community, error) { + community, err := m.GetByID(id) + if err != nil { + return nil, err + } + if community == nil { + return nil, ErrOrgNotFound + } + + community.RemoveOurselvesFromOrg(&m.identity.PublicKey) + community.Leave() + community.Spectate() + + if err = m.persistence.SaveCommunity(community); err != nil { + return nil, err + } + + return community, nil +} + func (m *Manager) AddMemberOwnerToCommunity(communityID types.HexBytes, pk *ecdsa.PublicKey) (*Community, error) { community, err := m.GetByID(communityID) if err != nil { diff --git a/protocol/messenger_communities.go b/protocol/messenger_communities.go index 296062bab..77275e34c 100644 --- a/protocol/messenger_communities.go +++ b/protocol/messenger_communities.go @@ -1702,7 +1702,7 @@ func (m *Messenger) LeaveCommunity(communityID types.HexBytes) (*MessengerRespon return nil, err } - mr, err := m.leaveCommunity(communityID, true) + mr, err := m.leaveCommunity(communityID) if err != nil { return nil, err } @@ -1756,7 +1756,7 @@ func (m *Messenger) LeaveCommunity(communityID types.HexBytes) (*MessengerRespon return mr, nil } -func (m *Messenger) leaveCommunity(communityID types.HexBytes, unsubsribeFromCommunity bool) (*MessengerResponse, error) { +func (m *Messenger) leaveCommunity(communityID types.HexBytes) (*MessengerResponse, error) { response := &MessengerResponse{} community, err := m.communitiesManager.LeaveCommunity(communityID) @@ -1779,11 +1779,21 @@ func (m *Messenger) leaveCommunity(communityID types.HexBytes, unsubsribeFromCom } } - if unsubsribeFromCommunity { - _, err = m.transport.RemoveFilterByChatID(communityID.String()) - if err != nil { - return nil, err - } + _, err = m.transport.RemoveFilterByChatID(communityID.String()) + if err != nil { + return nil, err + } + + response.AddCommunity(community) + return response, nil +} + +func (m *Messenger) kickedOutOfCommunity(communityID types.HexBytes) (*MessengerResponse, error) { + response := &MessengerResponse{} + + community, err := m.communitiesManager.KickedOutOfCommunity(communityID) + if err != nil { + return nil, err } response.AddCommunity(community) @@ -3230,7 +3240,7 @@ func (m *Messenger) handleSyncInstallationCommunity(messageState *ReceivedMessag return err } } else { - mr, err = m.leaveCommunity(syncCommunity.Id, true) + mr, err = m.leaveCommunity(syncCommunity.Id) if err != nil { logger.Debug("m.leaveCommunity error", zap.Error(err)) return err @@ -5865,12 +5875,8 @@ func (m *Messenger) processCommunityChanges(messageState *ReceivedMessageState) continue } - } else if changes.ShouldMemberLeave { - // this means we've been kicked by the community owner/admin, - // in this case we don't want to unsubscribe from community updates - // so we still get notified accordingly when something changes, - // hence, we're setting `unsubscribeFromCommunity` to `false` here - response, err := m.leaveCommunity(changes.Community.ID(), false) + } else if changes.MemberKicked { + response, err := m.kickedOutOfCommunity(changes.Community.ID()) if err != nil { m.logger.Error("cannot leave community", zap.Error(err)) continue