diff --git a/protocol/messenger.go b/protocol/messenger.go index 7a6e5e76a55..3b95d3c9114 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -928,135 +928,6 @@ func (m *Messenger) online() bool { } } -func (m *Messenger) buildContactCodeAdvertisement() (*protobuf.ContactCodeAdvertisement, error) { - if m.pushNotificationClient == nil || !m.pushNotificationClient.Enabled() { - return nil, nil - } - m.logger.Debug("adding push notification info to contact code bundle") - info, err := m.pushNotificationClient.MyPushNotificationQueryInfo() - if err != nil { - return nil, err - } - if len(info) == 0 { - return nil, nil - } - return &protobuf.ContactCodeAdvertisement{ - PushNotificationInfo: info, - }, nil -} - -// publishContactCode sends a public message wrapped in the encryption -// layer, which will propagate our bundle -func (m *Messenger) publishContactCode() error { - var payload []byte - m.logger.Debug("sending contact code") - contactCodeAdvertisement, err := m.buildContactCodeAdvertisement() - if err != nil { - m.logger.Error("could not build contact code advertisement", zap.Error(err)) - } - - if contactCodeAdvertisement == nil { - contactCodeAdvertisement = &protobuf.ContactCodeAdvertisement{} - } - - err = m.attachChatIdentity(contactCodeAdvertisement) - if err != nil { - return err - } - - if contactCodeAdvertisement.ChatIdentity != nil { - m.logger.Debug("attached chat identity", zap.Int("images len", len(contactCodeAdvertisement.ChatIdentity.Images))) - } else { - m.logger.Debug("no attached chat identity") - } - - payload, err = proto.Marshal(contactCodeAdvertisement) - if err != nil { - return err - } - - contactCodeTopic := transport.ContactCodeTopic(&m.identity.PublicKey) - rawMessage := common.RawMessage{ - LocalChatID: contactCodeTopic, - MessageType: protobuf.ApplicationMetadataMessage_CONTACT_CODE_ADVERTISEMENT, - Payload: payload, - } - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - _, err = m.sender.SendPublic(ctx, contactCodeTopic, rawMessage) - if err != nil { - m.logger.Warn("failed to send a contact code", zap.Error(err)) - } - - joinedCommunities, err := m.communitiesManager.Joined() - if err != nil { - return err - } - for _, community := range joinedCommunities { - rawMessage.LocalChatID = community.MemberUpdateChannelID() - rawMessage.PubsubTopic = community.PubsubTopic() - _, err = m.sender.SendPublic(ctx, rawMessage.LocalChatID, rawMessage) - if err != nil { - return err - } - } - - m.logger.Debug("contact code sent") - return err -} - -// contactCodeAdvertisement attaches a protobuf.ChatIdentity to the given protobuf.ContactCodeAdvertisement, -// if the `shouldPublish` conditions are met -func (m *Messenger) attachChatIdentity(cca *protobuf.ContactCodeAdvertisement) error { - contactCodeTopic := transport.ContactCodeTopic(&m.identity.PublicKey) - shouldPublish, err := m.shouldPublishChatIdentity(contactCodeTopic) - if err != nil { - return err - } - - if !shouldPublish { - return nil - } - - cca.ChatIdentity, err = m.createChatIdentity(privateChat) - if err != nil { - return err - } - - img, err := m.multiAccounts.GetIdentityImage(m.account.KeyUID, images.SmallDimName) - if err != nil { - return err - } - - displayName, err := m.settings.DisplayName() - if err != nil { - return err - } - - bio, err := m.settings.Bio() - if err != nil { - return err - } - - socialLinks, err := m.settings.GetSocialLinks() - if err != nil { - return err - } - - identityHash, err := m.getIdentityHash(displayName, bio, img, socialLinks) - if err != nil { - return err - } - - err = m.persistence.SaveWhenChatIdentityLastPublished(contactCodeTopic, identityHash) - if err != nil { - return err - } - - return nil -} - // handleStandaloneChatIdentity sends a standalone ChatIdentity message to a public or private channel if the publish criteria is met func (m *Messenger) handleStandaloneChatIdentity(chat *Chat) error { if chat.ChatType != ChatTypePublic && chat.ChatType != ChatTypeOneToOne { @@ -1551,23 +1422,6 @@ func (m *Messenger) watchPendingCommunityRequestToJoin() { }() } -func (m *Messenger) PublishIdentityImage() error { - // Reset last published time for ChatIdentity so new contact can receive data - err := m.resetLastPublishedTimeForChatIdentity() - if err != nil { - m.logger.Error("failed to reset publish time", zap.Error(err)) - return err - } - - // If not online, we schedule it - if !m.online() { - m.shouldPublishContactCode = true - return nil - } - - return m.publishContactCode() -} - // handlePushNotificationClientRegistration handles registration events func (m *Messenger) handlePushNotificationClientRegistrations(c chan struct{}) { go func() { diff --git a/protocol/messenger_communities.go b/protocol/messenger_communities.go index 54ff8a5d0b0..b3d822da917 100644 --- a/protocol/messenger_communities.go +++ b/protocol/messenger_communities.go @@ -682,6 +682,11 @@ func (m *Messenger) joinCommunity(ctx context.Context, communityID types.HexByte if err = m.subscribeToCommunityShard(communityID); err != nil { return nil, err } + + if err = m.publishContactCodeInCommunity(community); err != nil { + return nil, err + } + } communitySettings, err := m.communitiesManager.GetCommunitySettingsByID(communityID) diff --git a/protocol/messenger_contact_code.go b/protocol/messenger_contact_code.go new file mode 100644 index 00000000000..50b12370cc9 --- /dev/null +++ b/protocol/messenger_contact_code.go @@ -0,0 +1,175 @@ +package protocol + +import ( + "context" + "time" + + "github.com/golang/protobuf/proto" + "github.com/status-im/status-go/images" + "github.com/status-im/status-go/protocol/common" + "github.com/status-im/status-go/protocol/communities" + "github.com/status-im/status-go/protocol/protobuf" + "github.com/status-im/status-go/protocol/transport" + "go.uber.org/zap" +) + +func (m *Messenger) buildContactCodeAdvertisement() (*protobuf.ContactCodeAdvertisement, error) { + if m.pushNotificationClient == nil || !m.pushNotificationClient.Enabled() { + return nil, nil + } + m.logger.Debug("adding push notification info to contact code bundle") + info, err := m.pushNotificationClient.MyPushNotificationQueryInfo() + if err != nil { + return nil, err + } + if len(info) == 0 { + return nil, nil + } + return &protobuf.ContactCodeAdvertisement{ + PushNotificationInfo: info, + }, nil +} + +func (m *Messenger) PublishIdentityImage() error { + // Reset last published time for ChatIdentity so new contact can receive data + err := m.resetLastPublishedTimeForChatIdentity() + if err != nil { + m.logger.Error("failed to reset publish time", zap.Error(err)) + return err + } + + // If not online, we schedule it + if !m.online() { + m.shouldPublishContactCode = true + return nil + } + + return m.publishContactCode() +} + +func (m *Messenger) buildContactCodeRawMessage() (common.RawMessage, error) { + var payload []byte + m.logger.Debug("sending contact code") + contactCodeAdvertisement, err := m.buildContactCodeAdvertisement() + if err != nil { + m.logger.Error("could not build contact code advertisement", zap.Error(err)) + } + + if contactCodeAdvertisement == nil { + contactCodeAdvertisement = &protobuf.ContactCodeAdvertisement{} + } + + err = m.attachChatIdentity(contactCodeAdvertisement) + if err != nil { + return common.RawMessage{}, err + } + + if contactCodeAdvertisement.ChatIdentity != nil { + m.logger.Debug("attached chat identity", zap.Int("images len", len(contactCodeAdvertisement.ChatIdentity.Images))) + } else { + m.logger.Debug("no attached chat identity") + } + + payload, err = proto.Marshal(contactCodeAdvertisement) + if err != nil { + return common.RawMessage{}, err + } + + contactCodeTopic := transport.ContactCodeTopic(&m.identity.PublicKey) + return common.RawMessage{ + LocalChatID: contactCodeTopic, + MessageType: protobuf.ApplicationMetadataMessage_CONTACT_CODE_ADVERTISEMENT, + Payload: payload, + }, nil + +} + +func (m *Messenger) publishContactCodeInCommunity(community *communities.Community) error { + rawMessage, err := m.buildContactCodeRawMessage() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + rawMessage.LocalChatID = community.MemberUpdateChannelID() + rawMessage.PubsubTopic = community.PubsubTopic() + _, err = m.sender.SendPublic(ctx, rawMessage.LocalChatID, rawMessage) + return err +} + +// publishContactCode sends a public message wrapped in the encryption +// layer, which will propagate our bundle +func (m *Messenger) publishContactCode() error { + rawMessage, err := m.buildContactCodeRawMessage() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + _, err = m.sender.SendPublic(ctx, rawMessage.LocalChatID, rawMessage) + if err != nil { + m.logger.Warn("failed to send a contact code", zap.Error(err)) + } + + joinedCommunities, err := m.communitiesManager.Joined() + if err != nil { + return err + } + for _, community := range joinedCommunities { + rawMessage.LocalChatID = community.MemberUpdateChannelID() + rawMessage.PubsubTopic = community.PubsubTopic() + _, err = m.sender.SendPublic(ctx, rawMessage.LocalChatID, rawMessage) + if err != nil { + return err + } + } + + m.logger.Debug("contact code sent") + return err +} + +// contactCodeAdvertisement attaches a protobuf.ChatIdentity to the given protobuf.ContactCodeAdvertisement, +// if the `shouldPublish` conditions are met +func (m *Messenger) attachChatIdentity(cca *protobuf.ContactCodeAdvertisement) error { + contactCodeTopic := transport.ContactCodeTopic(&m.identity.PublicKey) + shouldPublish, err := m.shouldPublishChatIdentity(contactCodeTopic) + if err != nil { + return err + } + + if !shouldPublish { + return nil + } + + cca.ChatIdentity, err = m.createChatIdentity(privateChat) + if err != nil { + return err + } + + img, err := m.multiAccounts.GetIdentityImage(m.account.KeyUID, images.SmallDimName) + if err != nil { + return err + } + + displayName, err := m.settings.DisplayName() + if err != nil { + return err + } + + bio, err := m.settings.Bio() + if err != nil { + return err + } + + socialLinks, err := m.settings.GetSocialLinks() + if err != nil { + return err + } + + identityHash, err := m.getIdentityHash(displayName, bio, img, socialLinks) + if err != nil { + return err + } + + err = m.persistence.SaveWhenChatIdentityLastPublished(contactCodeTopic, identityHash) + if err != nil { + return err + } + + return nil +}