Skip to content

Commit

Permalink
feat(sync)!: leftovers work for sync fallback (#5794)
Browse files Browse the repository at this point in the history
* feat(sync)!: remove compatibility with v2.29

* feat(sync)_: add AC notifications when initiating the sync fallback

Needed for status-im/status-desktop#15750

Adds an AC notification when the syncing fails and the user is prompted to use a seed phrase instead.
There is one notification for the initiator (created) and one for the old account (received).
Once the flow is completed, ie the receiver presses Enable and sync,  the notifications are deleted

* test_: update test

* fix_: lint issue

* chore_: ignore tmp file generated by make lint-fix

* chore_: rename EnableAndSyncInstallation to EnableInstallationAndSync

* chore_: address review feedback

* chore_: revert changes to .gitignore

* fix_: simplify code

* fix_: keep old API

---------

Co-authored-by: Jonathan Rainville <[email protected]>
  • Loading branch information
qfrank and jrainville authored Sep 19, 2024
1 parent 6e5a32c commit f04a9a8
Show file tree
Hide file tree
Showing 11 changed files with 309 additions and 181 deletions.
3 changes: 3 additions & 0 deletions protocol/activity_center.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ const (
ActivityCenterNotificationTypeFirstCommunityTokenReceived
ActivityCenterNotificationTypeCommunityBanned
ActivityCenterNotificationTypeCommunityUnbanned
ActivityCenterNotificationTypeNewInstallationReceived
ActivityCenterNotificationTypeNewInstallationCreated
)

type ActivityCenterMembershipStatus int
Expand Down Expand Up @@ -87,6 +89,7 @@ type ActivityCenterNotification struct {
MembershipStatus ActivityCenterMembershipStatus `json:"membershipStatus"`
Name string `json:"name"`
Author string `json:"author"`
InstallationID string `json:"installationId"`
Type ActivityCenterType `json:"type"`
LastMessage *common.Message `json:"lastMessage"`
Message *common.Message `json:"message"`
Expand Down
36 changes: 28 additions & 8 deletions protocol/activity_center_persistence.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,10 @@ func (db sqlitePersistence) SaveActivityCenterNotification(notification *Activit
dismissed,
token_data,
deleted,
updated_at
updated_at,
installation_id
)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
`,
notification.ID,
notification.Timestamp,
Expand All @@ -168,6 +169,7 @@ func (db sqlitePersistence) SaveActivityCenterNotification(notification *Activit
encodedTokenData,
notification.Deleted,
notification.UpdatedAt,
notification.InstallationID,
)
if err != nil {
return 0, err
Expand Down Expand Up @@ -269,6 +271,7 @@ func (db sqlitePersistence) unmarshalActivityCenterNotificationRow(row *sql.Row)
var tokenDataBytes []byte
var name sql.NullString
var author sql.NullString
var installationID sql.NullString
notification := &ActivityCenterNotification{}
err := row.Scan(
&notification.ID,
Expand All @@ -288,7 +291,9 @@ func (db sqlitePersistence) unmarshalActivityCenterNotificationRow(row *sql.Row)
&name,
&author,
&tokenDataBytes,
&notification.UpdatedAt)
&notification.UpdatedAt,
&installationID,
)

if err != nil {
return nil, err
Expand All @@ -310,6 +315,10 @@ func (db sqlitePersistence) unmarshalActivityCenterNotificationRow(row *sql.Row)
notification.Author = author.String
}

if installationID.Valid {
notification.InstallationID = installationID.String
}

if len(tokenDataBytes) > 0 {
err = json.Unmarshal(tokenDataBytes, &notification.TokenData)
if err != nil {
Expand Down Expand Up @@ -359,6 +368,7 @@ func (db sqlitePersistence) unmarshalActivityCenterNotificationRows(rows *sql.Ro
var tokenDataBytes []byte
var name sql.NullString
var author sql.NullString
var installationID sql.NullString
notification := &ActivityCenterNotification{}
err := rows.Scan(
&notification.ID,
Expand All @@ -378,7 +388,9 @@ func (db sqlitePersistence) unmarshalActivityCenterNotificationRows(rows *sql.Ro
&author,
&tokenDataBytes,
&latestCursor,
&notification.UpdatedAt)
&notification.UpdatedAt,
&installationID,
)
if err != nil {
return "", nil, err
}
Expand All @@ -399,6 +411,10 @@ func (db sqlitePersistence) unmarshalActivityCenterNotificationRows(rows *sql.Ro
notification.Author = author.String
}

if installationID.Valid {
notification.InstallationID = installationID.String
}

if len(tokenDataBytes) > 0 {
tokenData := &ActivityTokenData{}
if err = json.Unmarshal(tokenDataBytes, &tokenData); err != nil {
Expand Down Expand Up @@ -539,7 +555,8 @@ func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activity
a.author,
a.token_data,
substr('0000000000000000000000000000000000000000000000000000000000000000' || a.timestamp, -64, 64) || hex(a.id) as cursor,
a.updated_at
a.updated_at,
a.installation_id
FROM activity_center_notifications a
LEFT JOIN chats c
ON
Expand Down Expand Up @@ -660,7 +677,8 @@ func (db sqlitePersistence) GetActivityCenterNotificationsByID(ids []types.HexBy
a.author,
a.token_data,
substr('0000000000000000000000000000000000000000000000000000000000000000' || a.timestamp, -64, 64) || hex(a.id) as cursor,
a.updated_at
a.updated_at,
a.installation_id
FROM activity_center_notifications a
LEFT JOIN chats c
ON
Expand Down Expand Up @@ -700,7 +718,8 @@ func (db sqlitePersistence) GetActivityCenterNotificationByID(id types.HexBytes)
c.name,
a.author,
a.token_data,
a.updated_at
a.updated_at,
a.installation_id
FROM activity_center_notifications a
LEFT JOIN chats c
ON
Expand Down Expand Up @@ -1334,7 +1353,8 @@ func (db sqlitePersistence) ActiveContactRequestNotification(contactID string) (
c.name,
a.author,
a.token_data,
a.updated_at
a.updated_at,
a.installation_id
FROM activity_center_notifications a
LEFT JOIN chats c ON c.id = a.chat_id
WHERE a.author = ?
Expand Down
51 changes: 51 additions & 0 deletions protocol/messenger.go
Original file line number Diff line number Diff line change
Expand Up @@ -3658,6 +3658,32 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
return m.saveDataAndPrepareResponse(messageState)
}

func (m *Messenger) deleteNotification(response *MessengerResponse, installationID string) error {
notification, err := m.persistence.GetActivityCenterNotificationByID(types.FromHex(installationID))
if err != nil {
return err
}

if notification == nil {
return nil
}

updatedAt := m.GetCurrentTimeInMillis()
notification.UpdatedAt = updatedAt
notification.Deleted = true
// we shouldn't sync deleted notification here,
// as the same user on different devices will receive the same message(CommunityCancelRequestToJoin) ?
err = m.persistence.DeleteActivityCenterNotificationByID(types.FromHex(installationID), updatedAt)
if err != nil {
m.logger.Error("failed to delete notification from Activity Center", zap.Error(err))
return err
}

// sending signal to client to remove the activity center notification from UI
response.AddActivityCenterNotification(notification)
return nil
}

func (m *Messenger) saveDataAndPrepareResponse(messageState *ReceivedMessageState) (*MessengerResponse, error) {
var err error
var contactsToSave []*Contact
Expand Down Expand Up @@ -3697,6 +3723,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(),
}

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

return true
})
if err != nil {
Expand Down
45 changes: 40 additions & 5 deletions protocol/messenger_pairing_and_syncing.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,38 @@ import (
"go.uber.org/zap"

"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/images"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/encryption/multidevice"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
)

func (m *Messenger) EnableAndSyncInstallation(request *requests.EnableAndSyncInstallation) error {
func (m *Messenger) EnableInstallationAndSync(request *requests.EnableInstallationAndSync) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return err
return nil, err
}
err := m.EnableInstallation(request.InstallationID)
if err != nil {
return err
return nil, err
}
response, err := m.SendPairInstallation(context.Background(), nil)
if err != nil {
return nil, err
}
err = m.SyncDevices(context.Background(), "", "", nil)
if err != nil {
return nil, err
}

// Delete AC notif
err = m.deleteNotification(response, request.InstallationID)
if err != nil {
return nil, err
}
return m.SyncDevices(context.Background(), "", "", nil)

return response, nil
}

func (m *Messenger) EnableInstallationAndPair(request *requests.EnableInstallationAndPair) (*MessengerResponse, error) {
Expand Down Expand Up @@ -53,7 +69,26 @@ func (m *Messenger) EnableInstallationAndPair(request *requests.EnableInstallati
i.Enabled = true
}
m.allInstallations.Store(request.InstallationID, i)
return m.SendPairInstallation(context.Background(), nil)
response, err := m.SendPairInstallation(context.Background(), nil)
if err != nil {
return nil, err
}

notification := &ActivityCenterNotification{
ID: types.FromHex(request.InstallationID),
Type: ActivityCenterNotificationTypeNewInstallationCreated,
InstallationID: m.installationID, // Put our own installation ID, as we're the initiator of the pairing
Timestamp: m.getTimesource().GetCurrentTime(),
Read: false,
Deleted: false,
UpdatedAt: m.GetCurrentTimeInMillis(),
}

err = m.addActivityCenterNotification(response, notification, nil)
if err != nil {
return nil, err
}
return response, err
}

// SendPairInstallation sends a pair installation message
Expand Down
3 changes: 2 additions & 1 deletion protocol/messenger_pairing_and_syncing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ func (s *MessengerPairingSuite) TestMessengerPairAfterSeedPhrase() {
)
s.Require().NoError(err)

s.Require().NoError(alice1.EnableAndSyncInstallation(&requests.EnableAndSyncInstallation{InstallationID: installationID2}))
_, err = alice1.EnableInstallationAndSync(&requests.EnableInstallationAndSync{InstallationID: installationID2})
s.Require().NoError(err)

// check if the display name is synced
err = tt.RetryWithBackOff(func() error {
Expand Down
Loading

0 comments on commit f04a9a8

Please sign in to comment.