diff --git a/protocol/messenger.go b/protocol/messenger.go index 5b2df38a4..92ae81018 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -3147,9 +3147,10 @@ type ReceivedMessageState struct { // 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 @@ -3322,6 +3323,7 @@ func (m *Messenger) buildMessageState() *ReceivedMessageState { 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), @@ -3735,28 +3737,31 @@ func (m *Messenger) saveDataAndPrepareResponse(messageState *ReceivedMessageStat } } - 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 + } + } 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 + } } } diff --git a/protocol/messenger_delete_message_for_me_test.go b/protocol/messenger_delete_message_for_me_test.go index 77288316a..72f0ecf20 100644 --- a/protocol/messenger_delete_message_for_me_test.go +++ b/protocol/messenger_delete_message_for_me_test.go @@ -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) @@ -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) } diff --git a/protocol/messenger_handler.go b/protocol/messenger_handler.go index 11f3312cf..bbb7d508a 100644 --- a/protocol/messenger_handler.go +++ b/protocol/messenger_handler.go @@ -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 } diff --git a/protocol/messenger_identity_display_name_test.go b/protocol/messenger_identity_display_name_test.go index b2048b127..8f6ca3e0b 100644 --- a/protocol/messenger_identity_display_name_test.go +++ b/protocol/messenger_identity_display_name_test.go @@ -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) @@ -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 diff --git a/protocol/messenger_installations_test.go b/protocol/messenger_installations_test.go index 48eb44cf9..760e160da 100644 --- a/protocol/messenger_installations_test.go +++ b/protocol/messenger_installations_test.go @@ -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) @@ -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() @@ -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) @@ -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 @@ -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) @@ -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 diff --git a/protocol/messenger_pairing_and_syncing.go b/protocol/messenger_pairing_and_syncing.go index 702e4593b..3995168c6 100644 --- a/protocol/messenger_pairing_and_syncing.go +++ b/protocol/messenger_pairing_and_syncing.go @@ -17,42 +17,55 @@ import ( "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) - if err != nil { - return nil, err - } - response, err := m.SendPairInstallation(context.Background(), nil) - if err != nil { - return nil, err - } - err = m.SyncDevices(context.Background(), "", "", nil) + + installation, err := m.EnableInstallation(request.InstallationID) if err != nil { return nil, err } - // Delete AC notif - err = m.deleteNotification(response, request.InstallationID) + response := &MessengerResponse{} + response.AddInstallation(installation) + + pairResponse, err := m.SendPairInstallation(context.Background(), request.InstallationID, nil) if err != nil { return nil, err } - return response, nil + if err = m.SyncDevices(context.Background(), "", "", nil); err != nil { + return nil, err + } + + if err = m.deleteNotification(pairResponse, request.InstallationID); err != nil { + return nil, err + } + + if err = pairResponse.Merge(response); err != nil { + return nil, err + } + + 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, @@ -62,20 +75,20 @@ func (m *Messenger) EnableInstallationAndPair(request *requests.EnableInstallati 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(), @@ -92,7 +105,7 @@ func (m *Messenger) EnableInstallationAndPair(request *requests.EnableInstallati } // 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 @@ -108,11 +121,13 @@ func (m *Messenger) SendPairInstallation(ctx context.Context, rawMessageHandler 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 @@ -496,20 +511,21 @@ func (m *Messenger) SetInstallationName(id string, name string) error { 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") } err := m.encryptor.EnableInstallation(&m.identity.PublicKey, id) if err != nil { - return err + return nil, err } 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 { diff --git a/protocol/messenger_pairing_and_syncing_test.go b/protocol/messenger_pairing_and_syncing_test.go index d632d064a..91825b620 100644 --- a/protocol/messenger_pairing_and_syncing_test.go +++ b/protocol/messenger_pairing_and_syncing_test.go @@ -7,6 +7,7 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/suite" + "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/multiaccounts/accounts" "github.com/status-im/status-go/multiaccounts/settings" "github.com/status-im/status-go/protocol/encryption/multidevice" @@ -58,12 +59,127 @@ func (s *MessengerPairingSuite) TestEnableNonExistingInstallation() { } -// TestMessengerPairAfterSeedPhrase tests the scenario where alice2 wants to sync with alice1 +type stubEnableInstallationAndPair struct { + installationID string + getInstallationIDInvokedFirst bool +} + +func (m *stubEnableInstallationAndPair) GetInstallationID() string { + if !m.getInstallationIDInvokedFirst { + m.getInstallationIDInvokedFirst = true + return m.installationID + } + return "wrong installation ID" +} + +func (m *stubEnableInstallationAndPair) Validate() error { + return nil +} + +// TestNewInstallationReceivedIsNotCreated tests the scenario where alice2 wants to pair with alice1 +// but the target installation ID is wrong so no AC notification(ActivityCenterNotificationTypeNewInstallationReceived) +// should be created for alice1 +func (s *MessengerPairingSuite) TestNewInstallationReceivedIsNotCreated() { + alice1 := s.m + alice2, err := newMessengerWithKey(s.shh, s.privateKey, s.logger, nil) + s.Require().NoError(err) + defer TearDownMessenger(&s.Suite, alice2) + + mockRequest := &stubEnableInstallationAndPair{installationID: alice1.installationID} + _, err = alice2.EnableInstallationAndPair(mockRequest) + s.Require().NoError(err) + + resp, err := WaitOnMessengerResponse( + alice1, + func(r *MessengerResponse) bool { + for _, i := range r.Installations() { + if i.ID == alice2.installationID { + return true + } + } + return false + }, + "no messages", + ) + s.Require().NoError(err) + s.Require().Len(resp.ActivityCenterNotifications(), 0) +} + +// TestNewInstallationCreatedIsNotDeleted tests the scenario +// 1. prepare AC NewInstallationCreated for alice2 +// 2. prepare AC NewInstallationCreated for alice3 +// 3. alice1.EnableInstallationAndSync +// 4. check AC NewInstallationCreated for alice3 is not deleted +func (s *MessengerPairingSuite) TestNewInstallationCreatedIsNotDeleted() { + alice1 := s.m + alice2, err := newMessengerWithKey(s.shh, s.privateKey, s.logger, nil) + s.Require().NoError(err) + alice3, err := newMessengerWithKey(s.shh, s.privateKey, s.logger, nil) + s.Require().NoError(err) + defer TearDownMessenger(&s.Suite, alice2) + defer TearDownMessenger(&s.Suite, alice3) + + // prepare AC NewInstallationCreated for alice2 + _, err = alice2.EnableInstallationAndPair(&requests.EnableInstallationAndPair{InstallationID: alice1.installationID}) + s.Require().NoError(err) + + // alice1 should get the installationID2 from alice2 + s.expectInstallationReceived(alice1, alice2.installationID) + + // prepare AC NewInstallationCreated for alice3 + _, err = alice3.EnableInstallationAndPair(&requests.EnableInstallationAndPair{InstallationID: alice1.installationID}) + s.Require().NoError(err) + + // alice1 should get the installationID3 from alice3 + s.expectInstallationReceived(alice1, alice3.installationID) + + _, err = alice1.EnableInstallationAndSync(&requests.EnableInstallationAndSync{InstallationID: alice2.installationID}) + s.Require().NoError(err) + + _, err = WaitOnMessengerResponse( + alice3, + func(r *MessengerResponse) bool { + for _, i := range r.Installations() { + if i.ID == alice1.installationID { + return true + } + } + return false + }, + "alice3 should get the installationID from alice1", + ) + s.Require().NoError(err) + + ac, err := alice3.ActivityCenterNotification(types.FromHex(alice1.installationID)) + s.Require().NoError(err) + s.Require().Equal(ActivityCenterNotificationTypeNewInstallationCreated, ac.Type) + s.Require().False(ac.Deleted) +} + +func (s *MessengerPairingSuite) expectInstallationReceived(m *Messenger, installationID string) { + resp, err := WaitOnMessengerResponse( + m, + func(r *MessengerResponse) bool { + for _, i := range r.Installations() { + if i.ID == installationID { + return true + } + } + return false + }, + "installation not received", + ) + s.Require().NoError(err) + s.Require().Len(resp.ActivityCenterNotifications(), 1) + s.Require().Equal(ActivityCenterNotificationTypeNewInstallationReceived, resp.ActivityCenterNotifications()[0].Type) +} + +// TestMessengerSyncFallback tests the scenario where alice2 wants to sync with alice1 // alice1 generated the connection string for bootstraping alice2 // alice2 failed to connect to alice1 and restored from seed phrase // alice2 get the installationID1 from alice1 via parsing the connection string // alice2 should get the display name from alice1 after pairing -func (s *MessengerPairingSuite) TestMessengerPairAfterSeedPhrase() { +func (s *MessengerPairingSuite) TestMessengerSyncFallback() { alice1 := s.m alice2, err := newMessengerWithKey(s.shh, s.privateKey, s.logger, nil) s.Require().NoError(err) @@ -87,23 +203,20 @@ func (s *MessengerPairingSuite) TestMessengerPairAfterSeedPhrase() { _, err = alice2.EnableInstallationAndPair(&requests.EnableInstallationAndPair{InstallationID: installationID1}) s.Require().NoError(err) - // alice1 should get the installationID1 from alice2 - _, err = WaitOnMessengerResponse( - alice1, - func(r *MessengerResponse) bool { - for _, i := range r.Installations() { - if i.ID == installationID2 { - return true - } - } - return false - }, - "no messages", - ) - s.Require().NoError(err) + // alice1 should get the installationID2 from alice2 + s.expectInstallationReceived(alice1, installationID2) - _, err = alice1.EnableInstallationAndSync(&requests.EnableInstallationAndSync{InstallationID: installationID2}) + // check response from alice1 + resp, err := alice1.EnableInstallationAndSync(&requests.EnableInstallationAndSync{InstallationID: installationID2}) s.Require().NoError(err) + installationID2Exist := false + for _, i := range resp.Installations() { + if i.ID == installationID2 { + installationID2Exist = true + break + } + } + s.Require().True(installationID2Exist) // check if the display name is synced err = tt.RetryWithBackOff(func() error { diff --git a/protocol/messenger_sync_bookmark_test.go b/protocol/messenger_sync_bookmark_test.go index f9e7e93a8..555ec23e5 100644 --- a/protocol/messenger_sync_bookmark_test.go +++ b/protocol/messenger_sync_bookmark_test.go @@ -40,7 +40,7 @@ func (s *MessengerSyncBookmarkSuite) TestSyncBookmark() { 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) @@ -60,7 +60,7 @@ func (s *MessengerSyncBookmarkSuite) TestSyncBookmark() { 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 diff --git a/protocol/messenger_sync_chat_test.go b/protocol/messenger_sync_chat_test.go index af4d913ce..08e06fa82 100644 --- a/protocol/messenger_sync_chat_test.go +++ b/protocol/messenger_sync_chat_test.go @@ -82,7 +82,7 @@ func (s *MessengerSyncChatSuite) 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) @@ -102,7 +102,7 @@ func (s *MessengerSyncChatSuite) 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) } diff --git a/protocol/messenger_sync_clear_history_test.go b/protocol/messenger_sync_clear_history_test.go index 691630fcf..ed4ebbe22 100644 --- a/protocol/messenger_sync_clear_history_test.go +++ b/protocol/messenger_sync_clear_history_test.go @@ -31,7 +31,7 @@ func (s *MessengerSyncClearHistory) pair() *Messenger { 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) @@ -49,7 +49,7 @@ func (s *MessengerSyncClearHistory) pair() *Messenger { 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) return theirMessenger diff --git a/protocol/messenger_sync_keycard_change_test.go b/protocol/messenger_sync_keycard_change_test.go index 324e7dc03..835854f14 100644 --- a/protocol/messenger_sync_keycard_change_test.go +++ b/protocol/messenger_sync_keycard_change_test.go @@ -58,7 +58,7 @@ func (s *MessengerSyncKeycardChangeSuite) SetupTest() { } err = s.other.SetInstallationMetadata(s.other.installationID, imOther) s.Require().NoError(err) - response, err := s.other.SendPairInstallation(context.Background(), nil) + response, err := s.other.SendPairInstallation(context.Background(), "", nil) s.Require().NoError(err) s.Require().NotNil(response) @@ -70,7 +70,7 @@ func (s *MessengerSyncKeycardChangeSuite) SetupTest() { ) s.Require().NoError(err) - err = s.main.EnableInstallation(s.other.installationID) + _, err = s.main.EnableInstallation(s.other.installationID) s.Require().NoError(err) // Pre-condition - both sides have to know about keypairs migrated to a keycards diff --git a/protocol/messenger_sync_keycards_state_test.go b/protocol/messenger_sync_keycards_state_test.go index 689fae29d..72b9b87e4 100644 --- a/protocol/messenger_sync_keycards_state_test.go +++ b/protocol/messenger_sync_keycards_state_test.go @@ -58,7 +58,7 @@ func (s *MessengerSyncKeycardsStateSuite) SetupTest() { } err = s.other.SetInstallationMetadata(s.other.installationID, imOther) s.Require().NoError(err) - response, err := s.other.SendPairInstallation(context.Background(), nil) + response, err := s.other.SendPairInstallation(context.Background(), "", nil) s.Require().NoError(err) s.Require().NotNil(response) @@ -70,7 +70,7 @@ func (s *MessengerSyncKeycardsStateSuite) SetupTest() { ) s.Require().NoError(err) - err = s.main.EnableInstallation(s.other.installationID) + _, err = s.main.EnableInstallation(s.other.installationID) s.Require().NoError(err) // Pre-condition - both sides have to know about keypairs migrated to a keycards diff --git a/protocol/messenger_sync_profile_picture_test.go b/protocol/messenger_sync_profile_picture_test.go index 96023738d..00e727ae8 100644 --- a/protocol/messenger_sync_profile_picture_test.go +++ b/protocol/messenger_sync_profile_picture_test.go @@ -35,7 +35,7 @@ func (s *MessengerSyncProfilePictureSuite) TestSyncProfilePicture() { 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) @@ -55,7 +55,7 @@ func (s *MessengerSyncProfilePictureSuite) TestSyncProfilePicture() { 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 happens via subscription triggered from within StoreIdentityImages diff --git a/protocol/messenger_sync_raw_messages.go b/protocol/messenger_sync_raw_messages.go index 8c173514b..3788085d8 100644 --- a/protocol/messenger_sync_raw_messages.go +++ b/protocol/messenger_sync_raw_messages.go @@ -312,7 +312,7 @@ func (m *Messenger) HandleSyncRawMessages(rawMessages []*protobuf.RawMessage) er } // if receiver already logged in before local pairing, we need force enable the installation, // AddInstallations won't make sure enable it, e.g. installation maybe already exist in db but not enabled yet - err = m.EnableInstallation(message.InstallationId) + _, err = m.EnableInstallation(message.InstallationId) if err != nil { return err } diff --git a/protocol/messenger_sync_saved_addresses_test.go b/protocol/messenger_sync_saved_addresses_test.go index 53f7d35ea..6de0eeca5 100644 --- a/protocol/messenger_sync_saved_addresses_test.go +++ b/protocol/messenger_sync_saved_addresses_test.go @@ -62,7 +62,7 @@ func (s *MessengerSyncSavedAddressesSuite) SetupTest() { } err = s.other.SetInstallationMetadata(s.other.installationID, imOther) s.Require().NoError(err) - response, err := s.other.SendPairInstallation(context.Background(), nil) + response, err := s.other.SendPairInstallation(context.Background(), "", nil) s.Require().NoError(err) s.Require().NotNil(response) @@ -74,7 +74,7 @@ func (s *MessengerSyncSavedAddressesSuite) SetupTest() { ) s.Require().NoError(err) - err = s.main.EnableInstallation(s.other.installationID) + _, err = s.main.EnableInstallation(s.other.installationID) s.Require().NoError(err) } diff --git a/protocol/messenger_sync_verification_test.go b/protocol/messenger_sync_verification_test.go index c6978aa80..5e6db4c65 100644 --- a/protocol/messenger_sync_verification_test.go +++ b/protocol/messenger_sync_verification_test.go @@ -43,7 +43,7 @@ func (s *MessengerSyncVerificationRequests) TestSyncVerificationRequests() { 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) @@ -63,7 +63,7 @@ func (s *MessengerSyncVerificationRequests) TestSyncVerificationRequests() { 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 @@ -107,7 +107,7 @@ func (s *MessengerSyncVerificationRequests) TestSyncTrust() { 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) @@ -127,7 +127,7 @@ func (s *MessengerSyncVerificationRequests) TestSyncTrust() { 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 diff --git a/protocol/messenger_sync_wallets_test.go b/protocol/messenger_sync_wallets_test.go index 50cfef6f5..a7a75bd04 100644 --- a/protocol/messenger_sync_wallets_test.go +++ b/protocol/messenger_sync_wallets_test.go @@ -101,7 +101,7 @@ func (s *MessengerSyncWalletSuite) TestSyncWallets() { } 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) @@ -121,7 +121,7 @@ func (s *MessengerSyncWalletSuite) TestSyncWallets() { 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) // Store seed phrase keypair with accounts on alice's device @@ -321,7 +321,7 @@ func (s *MessengerSyncWalletSuite) TestSyncWalletAccountsReorder() { } 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) @@ -341,7 +341,7 @@ func (s *MessengerSyncWalletSuite) TestSyncWalletAccountsReorder() { 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) // Move down account from position 1 to position 4 @@ -511,7 +511,7 @@ func (s *MessengerSyncWalletSuite) TestSyncWalletAccountOrderAfterDeletion() { } 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) @@ -531,7 +531,7 @@ func (s *MessengerSyncWalletSuite) TestSyncWalletAccountOrderAfterDeletion() { 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) // Trigger's a sync between devices diff --git a/protocol/messenger_testing_utils.go b/protocol/messenger_testing_utils.go index 272b6dfdc..d78c8d77b 100644 --- a/protocol/messenger_testing_utils.go +++ b/protocol/messenger_testing_utils.go @@ -277,7 +277,7 @@ func FindFirstByContentType(messages []*common.Message, contentType protobuf.Cha func PairDevices(s *suite.Suite, device1, device2 *Messenger) { // Send pairing data - response, err := device1.SendPairInstallation(context.Background(), nil) + response, err := device1.SendPairInstallation(context.Background(), "", nil) s.Require().NoError(err) s.Require().NotNil(response) s.Len(response.Chats(), 1) @@ -306,7 +306,7 @@ func PairDevices(s *suite.Suite, device1, device2 *Messenger) { s.Require().NotNil(response) // Ensure installation is enabled - err = device2.EnableInstallation(device1.installationID) + _, err = device2.EnableInstallation(device1.installationID) s.Require().NoError(err) } diff --git a/protocol/protobuf/pairing.proto b/protocol/protobuf/pairing.proto index 79580aa28..b56c927ae 100644 --- a/protocol/protobuf/pairing.proto +++ b/protocol/protobuf/pairing.proto @@ -91,8 +91,9 @@ message SyncPairInstallation { string installation_id = 2; string device_type = 3; string name = 4; - // following fields used for local pairing + // used for local pairing uint32 version = 5; + string target_installation_id = 6; } message SyncInstallationContactV2 { diff --git a/protocol/requests/enable_installation_and_pair.go b/protocol/requests/enable_installation_and_pair.go index 5a9453d43..1bbff2691 100644 --- a/protocol/requests/enable_installation_and_pair.go +++ b/protocol/requests/enable_installation_and_pair.go @@ -17,3 +17,7 @@ func (j *EnableInstallationAndPair) Validate() error { return nil } + +func (j *EnableInstallationAndPair) GetInstallationID() string { + return j.InstallationID +} diff --git a/server/pairing/raw_message_handler.go b/server/pairing/raw_message_handler.go index b9a189451..46ce5afed 100644 --- a/server/pairing/raw_message_handler.go +++ b/server/pairing/raw_message_handler.go @@ -36,7 +36,7 @@ func (s *SyncRawMessageHandler) CollectInstallationData(rawMessageCollector *Raw if err != nil { return err } - _, err = messenger.SendPairInstallation(context.TODO(), rawMessageCollector.dispatchMessage) + _, err = messenger.SendPairInstallation(context.TODO(), "", rawMessageCollector.dispatchMessage) return err } diff --git a/server/pairing/sync_device_test.go b/server/pairing/sync_device_test.go index 720db14cc..9598c9969 100644 --- a/server/pairing/sync_device_test.go +++ b/server/pairing/sync_device_test.go @@ -907,7 +907,7 @@ func (s *SyncDeviceSuite) TestTransferringKeystoreFilesAfterStopUisngKeycard() { s.Require().NoError(err) err = clientMessenger.SetInstallationMetadata(settings.InstallationID, im1) s.Require().NoError(err) - response, err := clientMessenger.SendPairInstallation(context.Background(), nil) + response, err := clientMessenger.SendPairInstallation(context.Background(), "", nil) s.Require().NoError(err) s.Require().NotNil(response) s.Require().Len(response.Chats(), 1) @@ -940,7 +940,7 @@ func (s *SyncDeviceSuite) TestTransferringKeystoreFilesAfterStopUisngKeycard() { } s.Require().True(found) - err = serverMessenger.EnableInstallation(settings.InstallationID) + _, err = serverMessenger.EnableInstallation(settings.InstallationID) s.Require().NoError(err) // Check if the logged in account is the same on server and client diff --git a/services/ext/api.go b/services/ext/api.go index 23a06cfe1..d7918fb4d 100644 --- a/services/ext/api.go +++ b/services/ext/api.go @@ -373,7 +373,8 @@ func (api *PublicAPI) RemoveFilters(parent context.Context, chats []*transport.F // EnableInstallation enables an installation for multi-device sync. func (api *PublicAPI) EnableInstallation(installationID string) error { - return api.service.messenger.EnableInstallation(installationID) + _, err := api.service.messenger.EnableInstallation(installationID) + return err } // DisableInstallation disables an installation for multi-device sync. @@ -1056,7 +1057,7 @@ func (api *PublicAPI) VerifiedUntrustworthy(ctx context.Context, request *reques } func (api *PublicAPI) SendPairInstallation(ctx context.Context) (*protocol.MessengerResponse, error) { - return api.service.messenger.SendPairInstallation(ctx, nil) + return api.service.messenger.SendPairInstallation(ctx, "", nil) } func (api *PublicAPI) SyncDevices(ctx context.Context, name, picture string) error { diff --git a/services/ext/service.go b/services/ext/service.go index cc4c92ecb..f51f94ea7 100644 --- a/services/ext/service.go +++ b/services/ext/service.go @@ -332,7 +332,8 @@ func (s *Service) verifyTransactionLoop(tick time.Duration, cancel <-chan struct } func (s *Service) EnableInstallation(installationID string) error { - return s.messenger.EnableInstallation(installationID) + _, err := s.messenger.EnableInstallation(installationID) + return err } // DisableInstallation disables an installation for multi-device sync.