Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix_: sync fallback notification #5888

Merged
merged 4 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions protocol/messenger.go
Original file line number Diff line number Diff line change
Expand Up @@ -3147,9 +3147,10 @@
// List of contacts modified
ModifiedContacts *stringBoolMap
// All installations in memory
AllInstallations *installationMap
// List of communities modified
AllInstallations *installationMap
ModifiedInstallations *stringBoolMap
// List of installations targeted to this device modified
TargetedInstallations *stringBoolMap
// Map of existing messages
ExistingMessagesMap map[string]bool
// EmojiReactions is a list of emoji reactions for the current batch
Expand Down Expand Up @@ -3322,6 +3323,7 @@
ModifiedContacts: new(stringBoolMap),
AllInstallations: m.allInstallations,
ModifiedInstallations: m.modifiedInstallations,
TargetedInstallations: new(stringBoolMap),
ExistingMessagesMap: make(map[string]bool),
EmojiReactions: make(map[string]*EmojiReaction),
GroupChatInvitations: make(map[string]*GroupChatInvitation),
Expand Down Expand Up @@ -3735,28 +3737,31 @@
}
}

if installation.Enabled {
// Delete AC notif since the installation is now enabled
err = m.deleteNotification(messageState.Response, id)
if err != nil {
m.logger.Error("error deleting notification", zap.Error(err))
return false
}
} else if id != m.installationID {
// Add activity center notification when we receive a new installation
notification := &ActivityCenterNotification{
ID: types.FromHex(id),
Type: ActivityCenterNotificationTypeNewInstallationReceived,
InstallationID: id,
Timestamp: m.getTimesource().GetCurrentTime(),
Read: false,
Deleted: false,
UpdatedAt: m.GetCurrentTimeInMillis(),
}
targeted, _ := messageState.TargetedInstallations.Load(id)
if targeted {
if installation.Enabled {
// Delete AC notif since the installation is now enabled
err = m.deleteNotification(messageState.Response, id)
if err != nil {
m.logger.Error("error deleting notification", zap.Error(err))
return false

Check warning on line 3747 in protocol/messenger.go

View check run for this annotation

Codecov / codecov/patch

protocol/messenger.go#L3746-L3747

Added lines #L3746 - L3747 were not covered by tests
}
} else if id != m.installationID {
// Add activity center notification when we receive a new installation
notification := &ActivityCenterNotification{
ID: types.FromHex(id),
Type: ActivityCenterNotificationTypeNewInstallationReceived,
InstallationID: id,
Timestamp: m.getTimesource().GetCurrentTime(),
Read: false,
Deleted: false,
UpdatedAt: m.GetCurrentTimeInMillis(),
}

err = m.addActivityCenterNotification(messageState.Response, notification, nil)
if err != nil {
return false
err = m.addActivityCenterNotification(messageState.Response, notification, nil)
if err != nil {
return false

Check warning on line 3763 in protocol/messenger.go

View check run for this annotation

Codecov / codecov/patch

protocol/messenger.go#L3763

Added line #L3763 was not covered by tests
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions protocol/messenger_delete_message_for_me_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (s *MessengerDeleteMessageForMeSuite) Pair() {
DeviceType: "alice2",
})
s.Require().NoError(err)
response, err := s.alice2.SendPairInstallation(context.Background(), nil)
response, err := s.alice2.SendPairInstallation(context.Background(), "", nil)
s.Require().NoError(err)
s.Require().NotNil(response)
s.Require().Len(response.Chats(), 1)
Expand All @@ -101,7 +101,7 @@ func (s *MessengerDeleteMessageForMeSuite) Pair() {
s.Require().Equal("alice2", actualInstallation.InstallationMetadata.Name)
s.Require().Equal("alice2", actualInstallation.InstallationMetadata.DeviceType)

err = s.alice1.EnableInstallation(s.alice2.installationID)
_, err = s.alice1.EnableInstallation(s.alice2.installationID)
s.Require().NoError(err)
}

Expand Down
2 changes: 2 additions & 0 deletions protocol/messenger_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,8 @@ func (m *Messenger) HandleSyncPairInstallation(state *ReceivedMessageState, mess
// TODO(samyoul) remove storing of an updated reference pointer?
state.AllInstallations.Store(message.InstallationId, installation)
state.ModifiedInstallations.Store(message.InstallationId, true)
targeted := message.TargetInstallationId == m.installationID
state.TargetedInstallations.Store(message.InstallationId, targeted)

return nil
}
Expand Down
4 changes: 2 additions & 2 deletions protocol/messenger_identity_display_name_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func (s *MessengerProfileDisplayNameHandlerSuite) TestDisplayNameSync() {
}
err = alicesOtherDevice.SetInstallationMetadata(alicesOtherDevice.installationID, im1)
s.Require().NoError(err)
response, err := alicesOtherDevice.SendPairInstallation(context.Background(), nil)
response, err := alicesOtherDevice.SendPairInstallation(context.Background(), "", nil)
s.Require().NoError(err)
s.Require().NotNil(response)
s.Require().Len(response.Chats(), 1)
Expand All @@ -133,7 +133,7 @@ func (s *MessengerProfileDisplayNameHandlerSuite) TestDisplayNameSync() {
s.Require().Equal("alice's-other-device", actualInstallation.InstallationMetadata.Name)
s.Require().Equal("alice's-other-device-type", actualInstallation.InstallationMetadata.DeviceType)

err = s.m.EnableInstallation(alicesOtherDevice.installationID)
_, err = s.m.EnableInstallation(alicesOtherDevice.installationID)
s.Require().NoError(err)

// Set new display name on alice's device
Expand Down
12 changes: 6 additions & 6 deletions protocol/messenger_installations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (s *MessengerInstallationSuite) TestReceiveInstallation() {
DeviceType: "their-device-type",
})
s.Require().NoError(err)
response, err := theirMessenger.SendPairInstallation(context.Background(), nil)
response, err := theirMessenger.SendPairInstallation(context.Background(), "", nil)
s.Require().NoError(err)
s.Require().NotNil(response)
s.Require().Len(response.Chats(), 1)
Expand All @@ -63,7 +63,7 @@ func (s *MessengerInstallationSuite) TestReceiveInstallation() {
s.Require().Equal("their-name", actualInstallation.InstallationMetadata.Name)
s.Require().Equal("their-device-type", actualInstallation.InstallationMetadata.DeviceType)

err = s.m.EnableInstallation(theirMessenger.installationID)
_, err = s.m.EnableInstallation(theirMessenger.installationID)
s.Require().NoError(err)

contactKey, err := crypto.GenerateKey()
Expand Down Expand Up @@ -242,7 +242,7 @@ func (s *MessengerInstallationSuite) TestSyncInstallation() {
DeviceType: "their-device-type",
})
s.Require().NoError(err)
response, err = theirMessenger.SendPairInstallation(context.Background(), nil)
response, err = theirMessenger.SendPairInstallation(context.Background(), "", nil)
s.Require().NoError(err)
s.Require().NotNil(response)
s.Require().Len(response.Chats(), 1)
Expand All @@ -262,7 +262,7 @@ func (s *MessengerInstallationSuite) TestSyncInstallation() {
s.Require().Equal("their-name", actualInstallation.InstallationMetadata.Name)
s.Require().Equal("their-device-type", actualInstallation.InstallationMetadata.DeviceType)

err = s.m.EnableInstallation(theirMessenger.installationID)
_, err = s.m.EnableInstallation(theirMessenger.installationID)
s.Require().NoError(err)

// sync
Expand Down Expand Up @@ -366,7 +366,7 @@ func (s *MessengerInstallationSuite) TestSyncInstallationNewMessages() {
DeviceType: "their-device-type",
})
s.Require().NoError(err)
response, err := bob2.SendPairInstallation(context.Background(), nil)
response, err := bob2.SendPairInstallation(context.Background(), "", nil)
s.Require().NoError(err)
s.Require().NotNil(response)
s.Require().Len(response.Chats(), 1)
Expand All @@ -382,7 +382,7 @@ func (s *MessengerInstallationSuite) TestSyncInstallationNewMessages() {
s.Require().NoError(err)
actualInstallation := response.Installations()[0]
s.Require().Equal(bob2.installationID, actualInstallation.ID)
err = bob1.EnableInstallation(bob2.installationID)
_, err = bob1.EnableInstallation(bob2.installationID)
s.Require().NoError(err)

// send a message from bob1 to alice, it should be received on both bob1 and bob2
Expand Down
64 changes: 40 additions & 24 deletions protocol/messenger_pairing_and_syncing.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,55 @@
"github.com/status-im/status-go/protocol/requests"
)

type InstallationIDProvider interface {
GetInstallationID() string
Validate() error
}

func (m *Messenger) EnableInstallationAndSync(request *requests.EnableInstallationAndSync) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}
err := m.EnableInstallation(request.InstallationID)

installation, err := m.EnableInstallation(request.InstallationID)
if err != nil {
return nil, err
}
response, err := m.SendPairInstallation(context.Background(), nil)

response := &MessengerResponse{}
response.AddInstallation(installation)

pairResponse, err := m.SendPairInstallation(context.Background(), request.InstallationID, nil)
if err != nil {
return nil, err
}
err = m.SyncDevices(context.Background(), "", "", nil)
if err != nil {

if err = m.SyncDevices(context.Background(), "", "", nil); err != nil {
return nil, err
}

// Delete AC notif
err = m.deleteNotification(response, request.InstallationID)
if err != nil {
if err = m.deleteNotification(pairResponse, request.InstallationID); err != nil {
return nil, err

Check warning on line 48 in protocol/messenger_pairing_and_syncing.go

View check run for this annotation

Codecov / codecov/patch

protocol/messenger_pairing_and_syncing.go#L48

Added line #L48 was not covered by tests
}

if err = pairResponse.Merge(response); err != nil {
return nil, err
}

return response, nil
return pairResponse, nil
}

func (m *Messenger) EnableInstallationAndPair(request *requests.EnableInstallationAndPair) (*MessengerResponse, error) {
func (m *Messenger) EnableInstallationAndPair(request InstallationIDProvider) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}

myIdentity := crypto.CompressPubkey(&m.identity.PublicKey)
timestamp := time.Now().UnixNano()
installationID := request.GetInstallationID()

installation := &multidevice.Installation{
ID: request.InstallationID,
ID: installationID,
Enabled: true,
Version: 2,
Timestamp: timestamp,
Expand All @@ -62,20 +75,20 @@
if err != nil {
return nil, err
}
i, ok := m.allInstallations.Load(request.InstallationID)
i, ok := m.allInstallations.Load(installationID)
if !ok {
i = installation
} else {
i.Enabled = true
}
m.allInstallations.Store(request.InstallationID, i)
response, err := m.SendPairInstallation(context.Background(), nil)
m.allInstallations.Store(installationID, i)
response, err := m.SendPairInstallation(context.Background(), request.GetInstallationID(), nil)
if err != nil {
return nil, err
}

notification := &ActivityCenterNotification{
ID: types.FromHex(request.InstallationID),
ID: types.FromHex(installationID),
Type: ActivityCenterNotificationTypeNewInstallationCreated,
InstallationID: m.installationID, // Put our own installation ID, as we're the initiator of the pairing
Timestamp: m.getTimesource().GetCurrentTime(),
Expand All @@ -92,7 +105,7 @@
}

// SendPairInstallation sends a pair installation message
func (m *Messenger) SendPairInstallation(ctx context.Context, rawMessageHandler RawMessageHandler) (*MessengerResponse, error) {
func (m *Messenger) SendPairInstallation(ctx context.Context, targetInstallationID string, rawMessageHandler RawMessageHandler) (*MessengerResponse, error) {
var err error
var response MessengerResponse

Expand All @@ -108,11 +121,13 @@
clock, chat := m.getLastClockWithRelatedChat()

pairMessage := &protobuf.SyncPairInstallation{
Clock: clock,
Name: installation.InstallationMetadata.Name,
InstallationId: installation.ID,
DeviceType: installation.InstallationMetadata.DeviceType,
Version: installation.Version}
Clock: clock,
Name: installation.InstallationMetadata.Name,
InstallationId: installation.ID,
DeviceType: installation.InstallationMetadata.DeviceType,
Version: installation.Version,
TargetInstallationId: targetInstallationID,
}
encodedMessage, err := proto.Marshal(pairMessage)
if err != nil {
return nil, err
Expand Down Expand Up @@ -496,20 +511,21 @@
return m.encryptor.SetInstallationName(m.IdentityPublicKey(), id, name)
}

func (m *Messenger) EnableInstallation(id string) error {
// EnableInstallation enables an installation and returns the installation
func (m *Messenger) EnableInstallation(id string) (*multidevice.Installation, error) {
installation, ok := m.allInstallations.Load(id)
if !ok {
return errors.New("no installation found")
return nil, errors.New("no installation found")

Check warning on line 518 in protocol/messenger_pairing_and_syncing.go

View check run for this annotation

Codecov / codecov/patch

protocol/messenger_pairing_and_syncing.go#L518

Added line #L518 was not covered by tests
}

err := m.encryptor.EnableInstallation(&m.identity.PublicKey, id)
if err != nil {
return err
return nil, err

Check warning on line 523 in protocol/messenger_pairing_and_syncing.go

View check run for this annotation

Codecov / codecov/patch

protocol/messenger_pairing_and_syncing.go#L523

Added line #L523 was not covered by tests
}
installation.Enabled = true
// TODO(samyoul) remove storing of an updated reference pointer?
m.allInstallations.Store(id, installation)
return nil
return installation, nil
}

func (m *Messenger) DisableInstallation(id string) error {
Expand Down
Loading