Backup removed & added by them contacts

This commit is contained in:
Andrea Maria Piana 2021-10-22 15:20:42 +01:00
parent 301325a22e
commit a7b0c6c933
20 changed files with 341 additions and 504 deletions

View File

@ -185,7 +185,7 @@ func main() {
return
}
err = wakuext.SaveContact(context.Background(), contact)
_, err = wakuext.AddContact(context.Background(), contact.ID)
if err != nil {
return
}

View File

@ -764,3 +764,15 @@ func (db *Database) SetLastBackup(time uint64) error {
_, err := db.db.Exec("UPDATE settings SET last_backup = ?", time)
return err
}
func (db *Database) ENSName() (string, error) {
var result sql.NullString
err := db.db.QueryRow("SELECT preferred_name FROM settings WHERE synthetic_id = 'id'").Scan(&result)
if err == sql.ErrNoRows {
return "", nil
}
if result.Valid {
return result.String, nil
}
return "", err
}

View File

@ -28,6 +28,7 @@ var (
DappsAddress: types.HexToAddress("0xD1300f99fDF7346986CbC766903245087394ecd0"),
InstallationID: "d3efcff6-cffa-560e-a547-21d3858cbc51",
KeyUID: "0x4e8129f3edfc004875be17bf468a784098a9f69b53c095be1f52deff286935ab",
BackupEnabled: true,
LatestDerivedPath: 0,
Name: "Jittery Cornflowerblue Kingbird",
Networks: &networks,

View File

@ -1,209 +0,0 @@
// In order to run these tests, you must run a PostgreSQL database.
//
// Using Docker:
// docker run -e POSTGRES_HOST_AUTH_METHOD=trust -d -p 5432:5432 postgres:9.6-alpine
//
package protocol
import (
"context"
"crypto/ecdsa"
"testing"
"github.com/stretchr/testify/suite"
"go.uber.org/zap"
bindata "github.com/status-im/migrate/v4/source/go_bindata"
appmetricsDB "github.com/status-im/status-go/appmetrics"
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/postgres"
"github.com/status-im/status-go/protocol/anonmetrics"
"github.com/status-im/status-go/protocol/anonmetrics/migrations"
"github.com/status-im/status-go/protocol/tt"
"github.com/status-im/status-go/services/appmetrics"
"github.com/status-im/status-go/waku"
)
func TestMessengerAnonMetricsSuite(t *testing.T) {
suite.Run(t, new(MessengerAnonMetricsSuite))
}
type MessengerAnonMetricsSuite struct {
suite.Suite
alice *Messenger // client instance of Messenger
bob *Messenger // server instance of Messenger
aliceKey *ecdsa.PrivateKey // private key for the alice instance of Messenger
bobKey *ecdsa.PrivateKey // private key for the bob instance of Messenger
// If one wants to send messages between different instances of Messenger,
// a single Waku service should be shared.
shh types.Waku
logger *zap.Logger
}
func (s *MessengerAnonMetricsSuite) SetupSuite() {
// ResetDefaultTestPostgresDB Required to completely reset the Postgres DB
err := postgres.ResetDefaultTestPostgresDB()
s.NoError(err)
}
func (s *MessengerAnonMetricsSuite) SetupTest() {
var err error
s.logger = tt.MustCreateTestLogger()
// Setup Waku things
config := waku.DefaultConfig
config.MinimumAcceptedPoW = 0
shh := waku.New(&config, s.logger)
s.shh = gethbridge.NewGethWakuWrapper(shh)
s.Require().NoError(shh.Start())
// Generate private keys for Alice and Bob
s.aliceKey, err = crypto.GenerateKey()
s.Require().NoError(err)
s.bobKey, err = crypto.GenerateKey()
s.Require().NoError(err)
// Generate Alice Messenger as the client
amcc := &anonmetrics.ClientConfig{
ShouldSend: true,
SendAddress: &s.bobKey.PublicKey,
Active: anonmetrics.ActiveClientPhrase,
}
s.alice, err = newMessengerWithKey(s.shh, s.aliceKey, s.logger, []Option{WithAnonMetricsClientConfig(amcc)})
s.Require().NoError(err)
_, err = s.alice.Start()
s.Require().NoError(err)
// Generate Bob Messenger as the Server
amsc := &anonmetrics.ServerConfig{
Enabled: true,
PostgresURI: postgres.DefaultTestURI,
Active: anonmetrics.ActiveServerPhrase,
}
s.bob, err = newMessengerWithKey(s.shh, s.bobKey, s.logger, []Option{WithAnonMetricsServerConfig(amsc)})
s.Require().NoError(err)
_, err = s.bob.Start()
s.Require().NoError(err)
}
func (s *MessengerAnonMetricsSuite) TearDownTest() {
// Down migrate the DB
if s.bob.anonMetricsServer != nil {
postgresMigration := bindata.Resource(migrations.AssetNames(), migrations.Asset)
m, err := anonmetrics.MakeMigration(s.bob.anonMetricsServer.PostgresDB, postgresMigration)
s.NoError(err)
err = m.Down()
s.NoError(err)
}
// Shutdown messengers
s.NoError(s.alice.Shutdown())
s.alice = nil
s.NoError(s.bob.Shutdown())
s.bob = nil
_ = s.logger.Sync()
}
func (s *MessengerAnonMetricsSuite) TestReceiveAnonMetric() {
// Create the appmetrics API to simulate incoming metrics from `status-react`
ama := appmetrics.NewAPI(appmetricsDB.NewDB(s.alice.database))
// Generate and store some metrics to Alice
ams := appmetricsDB.GenerateMetrics(10)
err := ama.SaveAppMetrics(context.Background(), ams)
s.Require().NoError(err)
// Check that we have what we stored
amsdb, err := ama.GetAppMetrics(context.Background(), 100, 0)
s.Require().NoError(err)
s.Require().Len(amsdb.AppMetrics, 10)
// Wait for messages to arrive at bob
_, err = WaitOnMessengerResponse(
s.bob,
func(r *MessengerResponse) bool { return len(r.AnonymousMetrics) > 0 },
"no anonymous metrics received",
)
s.Require().NoError(err)
// Get app metrics from postgres DB
bobMetrics, err := s.bob.anonMetricsServer.GetAppMetrics(100, 0)
s.Require().NoError(err)
s.Require().Len(bobMetrics, 5)
// Check the values of received and stored metrics against the broadcast metrics
for i, bobMetric := range bobMetrics {
s.Require().True(bobMetric.CreatedAt.Equal(amsdb.AppMetrics[i].CreatedAt), "created_at values are equal")
s.Require().Exactly(bobMetric.SessionID, amsdb.AppMetrics[i].SessionID, "session_id matched exactly")
s.Require().Exactly(bobMetric.Value, amsdb.AppMetrics[i].Value, "value matches exactly")
s.Require().Exactly(bobMetric.Event, amsdb.AppMetrics[i].Event, "event matches exactly")
s.Require().Exactly(bobMetric.OS, amsdb.AppMetrics[i].OS, "operating system matches exactly")
s.Require().Exactly(bobMetric.AppVersion, amsdb.AppMetrics[i].AppVersion, "app version matches exactly")
}
}
// TestActivationIsOff tests if using the incorrect activation phrase for the anon metric client / server deactivates
// the client / server. This test can be removed when / if the anon metrics functionality is reintroduced / re-approved.
func (s *MessengerAnonMetricsSuite) TestActivationIsOff() {
var err error
// Check the set up messengers are in the expected state with the correct activation phrases
s.NotNil(s.alice.anonMetricsClient)
s.NotNil(s.bob.anonMetricsServer)
// Generate Alice Messenger as the client with an incorrect phrase
amcc := &anonmetrics.ClientConfig{
ShouldSend: true,
SendAddress: &s.bobKey.PublicKey,
Active: "the wrong client phrase",
}
s.alice, err = newMessengerWithKey(s.shh, s.aliceKey, s.logger, []Option{WithAnonMetricsClientConfig(amcc)})
s.NoError(err)
_, err = s.alice.Start()
s.Require().NoError(err)
s.Nil(s.alice.anonMetricsClient)
// Generate Alice Messenger as the client with an no activation phrase
amcc = &anonmetrics.ClientConfig{
ShouldSend: true,
SendAddress: &s.bobKey.PublicKey,
}
s.alice, err = newMessengerWithKey(s.shh, s.aliceKey, s.logger, []Option{WithAnonMetricsClientConfig(amcc)})
s.NoError(err)
_, err = s.alice.Start()
s.Require().NoError(err)
s.Nil(s.alice.anonMetricsClient)
// Generate Bob Messenger as the Server with an incorrect phrase
amsc := &anonmetrics.ServerConfig{
Enabled: true,
PostgresURI: postgres.DefaultTestURI,
Active: "the wrong server phrase",
}
s.bob, err = newMessengerWithKey(s.shh, s.bobKey, s.logger, []Option{WithAnonMetricsServerConfig(amsc)})
s.Require().NoError(err)
s.Nil(s.bob.anonMetricsServer)
// Generate Bob Messenger as the Server with no activation phrase
amsc = &anonmetrics.ServerConfig{
Enabled: true,
PostgresURI: postgres.DefaultTestURI,
}
s.bob, err = newMessengerWithKey(s.shh, s.bobKey, s.logger, []Option{WithAnonMetricsServerConfig(amsc)})
s.Require().NoError(err)
s.Nil(s.bob.anonMetricsServer)
}

View File

@ -73,6 +73,9 @@ type Contact struct {
// updates should be discarded if last updated is less than the one stored
LastUpdated uint64 `json:"lastUpdated"`
// LastUpdatedLocally is the last time we updated the contact locally
LastUpdatedLocally uint64 `json:"lastUpdatedLocally"`
LocalNickname string `json:"localNickname,omitempty"`
Images map[string]images.IdentityImage `json:"images"`

View File

@ -2459,14 +2459,15 @@ func (m *Messenger) syncContact(ctx context.Context, contact *Contact) error {
}
syncMessage := &protobuf.SyncInstallationContactV2{
Clock: clock,
Id: contact.ID,
EnsName: ensName,
LocalNickname: contact.LocalNickname,
Added: contact.Added,
Blocked: contact.Blocked,
Muted: muted,
Removed: contact.Removed,
LastUpdatedLocally: contact.LastUpdatedLocally,
LastUpdated: contact.LastUpdated,
Id: contact.ID,
EnsName: ensName,
LocalNickname: contact.LocalNickname,
Added: contact.Added,
Blocked: contact.Blocked,
Muted: muted,
Removed: contact.Removed,
}
encodedMessage, err := proto.Marshal(syncMessage)

View File

@ -68,6 +68,7 @@ func (m *Messenger) startBackupLoop() {
m.logger.Error("failed to backup data", zap.Error(err))
}
case <-m.quit:
ticker.Stop()
return
}
}
@ -135,7 +136,6 @@ func (m *Messenger) syncBackupContact(ctx context.Context, contact *Contact) *pr
if contact.IsSyncing {
return nil
}
clock, _ := m.getLastClockWithRelatedChat()
var ensName string
if contact.ENSVerified {
@ -149,13 +149,15 @@ func (m *Messenger) syncBackupContact(ctx context.Context, contact *Contact) *pr
}
return &protobuf.SyncInstallationContactV2{
Clock: clock,
Id: contact.ID,
EnsName: ensName,
LocalNickname: contact.LocalNickname,
Added: contact.Added,
Blocked: contact.Blocked,
Muted: muted,
Removed: contact.Removed,
LastUpdatedLocally: contact.LastUpdatedLocally,
LastUpdated: contact.LastUpdated,
Id: contact.ID,
EnsName: ensName,
LocalNickname: contact.LocalNickname,
Added: contact.Added,
Blocked: contact.Blocked,
Muted: muted,
HasAddedUs: contact.HasAddedUs,
Removed: contact.Removed,
}
}

View File

@ -186,3 +186,86 @@ func (s *MessengerBackupSuite) TestBackupContactsGreaterThanBatch() {
s.Require().NoError(err)
s.Require().Len(bob2.AddedContacts(), BackupContactsPerBatch*2)
}
func (s *MessengerBackupSuite) TestBackupRemovedContact() {
bob1 := s.m
// Create bob2
bob2, err := newMessengerWithKey(s.shh, bob1.identity, s.logger, nil)
s.Require().NoError(err)
_, err = bob2.Start()
s.Require().NoError(err)
// Create 2 contacts on bob 1
contact1Key, err := crypto.GenerateKey()
s.Require().NoError(err)
contactID1 := types.EncodeHex(crypto.FromECDSAPub(&contact1Key.PublicKey))
_, err = bob1.AddContact(context.Background(), contactID1)
s.Require().NoError(err)
contact2Key, err := crypto.GenerateKey()
s.Require().NoError(err)
contactID2 := types.EncodeHex(crypto.FromECDSAPub(&contact2Key.PublicKey))
_, err = bob1.AddContact(context.Background(), contactID2)
s.Require().NoError(err)
s.Require().Len(bob1.Contacts(), 2)
actualContacts := bob1.Contacts()
if actualContacts[0].ID == contactID1 {
s.Require().Equal(actualContacts[0].ID, contactID1)
s.Require().Equal(actualContacts[1].ID, contactID2)
} else {
s.Require().Equal(actualContacts[0].ID, contactID2)
s.Require().Equal(actualContacts[1].ID, contactID1)
}
// Bob 2 add one of the same contacts
_, err = bob2.AddContact(context.Background(), contactID2)
s.Require().NoError(err)
// Bob 1 now removes one of the contact that was also on bob 2
_, err = bob1.RemoveContact(context.Background(), contactID2)
s.Require().NoError(err)
// Backup
clock, err := bob1.BackupData(context.Background())
s.Require().NoError(err)
// Safety check
s.Require().Len(bob2.Contacts(), 1)
// Wait for the message to reach its destination
_, err = WaitOnMessengerResponse(
bob2,
func(r *MessengerResponse) bool {
_, err := s.m.RetrieveAll()
if err != nil {
s.logger.Info("Failed")
return false
}
if len(bob2.Contacts()) != 1 && bob2.Contacts()[0].ID != contactID1 {
return false
}
return true
},
"contacts not backed up",
)
// Bob 2 should remove the contact
s.Require().NoError(err)
s.Require().Len(bob2.AddedContacts(), 1)
s.Require().Equal(contactID1, bob2.AddedContacts()[0].ID)
lastBackup, err := bob1.lastBackup()
s.Require().NoError(err)
s.Require().NotEmpty(lastBackup)
s.Require().Equal(clock, lastBackup)
}

View File

@ -59,30 +59,36 @@ func (s *MessengerContactUpdateSuite) newMessenger(shh types.Waku) *Messenger {
func (s *MessengerContactUpdateSuite) TestReceiveContactUpdate() {
theirName := "ens-name.stateofus.eth"
theirPicture := "their-picture"
contactID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
theirMessenger := s.newMessenger(s.shh)
_, err := theirMessenger.Start()
s.Require().NoError(err)
// Set ENS name
err = theirMessenger.settings.SaveSetting("preferred-name", theirName)
s.Require().NoError(err)
theirContactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
response, err := theirMessenger.SendContactUpdate(context.Background(), contactID, theirName, theirPicture)
response, err := theirMessenger.AddContact(context.Background(), contactID)
s.Require().NoError(err)
s.Require().NotNil(response)
s.Require().Len(response.Contacts, 1)
contact := response.Contacts[0]
// It should not add the contact, as that's left to `SaveContact`
s.Require().False(contact.Added)
// It should add the contact
s.Require().True(contact.Added)
// add contact
contact.Added = true
s.Require().NoError(theirMessenger.SaveContact(contact))
s.Require().Len(response.Chats(), 1)
chat := response.Chats()[0]
s.Require().False(chat.Active, "It does not create an active chat")
// It should create a profile chat & a one to one chat
s.Require().Len(response.Chats(), 2)
chats := response.Chats()
if chats[0].ChatType == ChatTypeOneToOne {
s.Require().False(chats[0].Active)
} else {
s.Require().False(chats[1].Active)
}
// Wait for the message to reach its destination
response, err = WaitOnMessengerResponse(

View File

@ -3,6 +3,7 @@ package protocol
import (
"context"
"crypto/ecdsa"
"errors"
"github.com/golang/protobuf/proto"
@ -11,10 +12,6 @@ import (
"github.com/status-im/status-go/protocol/transport"
)
func (m *Messenger) SaveContact(contact *Contact) error {
return m.saveContact(contact)
}
func (m *Messenger) AddContact(ctx context.Context, pubKey string) (*MessengerResponse, error) {
contact, ok := m.allContacts.Load(pubKey)
if !ok {
@ -28,6 +25,7 @@ func (m *Messenger) AddContact(ctx context.Context, pubKey string) (*MessengerRe
if !contact.Added {
contact.Added = true
}
contact.LastUpdatedLocally = m.getTimesource().GetCurrentTime()
// We sync the contact with the other devices
err := m.syncContact(context.Background(), contact)
@ -63,21 +61,45 @@ func (m *Messenger) AddContact(ctx context.Context, pubKey string) (*MessengerRe
return nil, err
}
// Fetch contact code
publicKey, err := contact.PublicKey()
if err != nil {
return nil, err
}
filter, err := m.transport.JoinPrivate(publicKey)
if err != nil {
return nil, err
}
m.scheduleSyncFilter(filter)
// Finally we send a contact update so they are notified we added them
// TODO: ens and picture are both blank for now
response, err := m.sendContactUpdate(context.Background(), pubKey, "", "")
ensName, err := m.settings.ENSName()
if err != nil {
return nil, err
}
response, err := m.sendContactUpdate(context.Background(), pubKey, ensName, "")
if err != nil {
return nil, err
}
// Send profile picture with contact request
chat, ok := m.allChats.Load(contact.ID)
if !ok {
chat = OneToOneFromPublicKey(publicKey, m.getTimesource())
chat.Active = false
if err := m.saveChat(chat); err != nil {
return nil, err
}
}
err = m.handleStandaloneChatIdentity(chat)
if err != nil {
return nil, err
}
response.AddChat(profileChat)
publicKey, err := contact.PublicKey()
if err != nil {
return nil, err
}
// TODO: Add filters to response
_, err = m.transport.InitFilters([]string{profileChat.ID}, []*ecdsa.PublicKey{publicKey})
if err != nil {
return nil, err
@ -106,6 +128,7 @@ func (m *Messenger) removeContact(ctx context.Context, response *MessengerRespon
}
contact.Remove()
contact.LastUpdatedLocally = m.getTimesource().GetCurrentTime()
err := m.persistence.SaveContact(contact, nil)
if err != nil {
@ -181,8 +204,32 @@ func (m *Messenger) GetContactByID(pubKey string) *Contact {
return contact
}
func (m *Messenger) SetLocalNickname(pubKey string, nickname string) (*MessengerResponse, error) {
contact, ok := m.allContacts.Load(pubKey)
if !ok {
return nil, errors.New("not existing contact")
}
clock := m.getTimesource().GetCurrentTime()
contact.LocalNickname = nickname
contact.LastUpdatedLocally = clock
response := &MessengerResponse{}
response.Contacts = []*Contact{contact}
err := m.syncContact(context.Background(), contact)
if err != nil {
return nil, err
}
return response, nil
}
func (m *Messenger) BlockContact(contact *Contact) ([]*Chat, error) {
contact.Block()
contact.LastUpdatedLocally = m.getTimesource().GetCurrentTime()
chats, err := m.persistence.BlockContact(contact)
if err != nil {
return nil, err
@ -208,61 +255,6 @@ func (m *Messenger) BlockContact(contact *Contact) ([]*Chat, error) {
return chats, nil
}
func (m *Messenger) saveContact(contact *Contact) error {
name, identicon, err := generateAliasAndIdenticon(contact.ID)
if err != nil {
return err
}
contact.Identicon = identicon
contact.Alias = name
if m.shouldSyncContact(contact) {
if m.isNewContact(contact) {
publicKey, err := contact.PublicKey()
if err != nil {
return err
}
filter, err := m.transport.JoinPrivate(publicKey)
if err != nil {
return err
}
m.scheduleSyncFilter(filter)
}
err := m.syncContact(context.Background(), contact)
if err != nil {
return err
}
}
// We check if it should re-register with the push notification server
shouldReregisterForPushNotifications := (m.isNewContact(contact) || m.removedContact(contact))
err = m.persistence.SaveContact(contact, nil)
if err != nil {
return err
}
m.allContacts.Store(contact.ID, contact)
// Reregister only when data has changed
if shouldReregisterForPushNotifications {
err := m.resetLastPublishedTimeForChatIdentity()
if err != nil {
return err
}
// Publish contact code
err = m.publishContactCode()
if err != nil {
return err
}
return m.reregisterForPushNotifications()
}
return nil
}
// Send contact updates to all contacts added by us
func (m *Messenger) SendContactUpdates(ctx context.Context, ensName, profileImage string) (err error) {
myID := contactIDFromPublicKey(&m.identity.PublicKey)
@ -298,12 +290,8 @@ func (m *Messenger) sendContactUpdate(ctx context.Context, chatID, ensName, prof
var response MessengerResponse
contact, ok := m.allContacts.Load(chatID)
if !ok {
var err error
contact, err = buildContactFromPkString(chatID)
if err != nil {
return nil, err
}
if !ok || !contact.Added {
return nil, nil
}
chat, ok := m.allChats.Load(chatID)
@ -348,29 +336,5 @@ func (m *Messenger) sendContactUpdate(ctx context.Context, chatID, ensName, prof
if err != nil {
return nil, err
}
return &response, m.saveContact(contact)
}
func (m *Messenger) isNewContact(contact *Contact) bool {
previousContact, ok := m.allContacts.Load(contact.ID)
return contact.Added && (!ok || !previousContact.Added)
}
func (m *Messenger) shouldSyncContact(contact *Contact) bool {
previousContact, ok := m.allContacts.Load(contact.ID)
if !ok {
return contact.Added
}
return contact.LocalNickname != previousContact.LocalNickname ||
contact.Added != previousContact.Added ||
previousContact.Blocked != contact.Blocked
}
func (m *Messenger) removedContact(contact *Contact) bool {
previousContact, ok := m.allContacts.Load(contact.ID)
if !ok {
return false
}
return previousContact.Added && !contact.Added
return &response, nil
}

View File

@ -312,7 +312,11 @@ func (m *Messenger) HandleSyncInstallationContact(state *ReceivedMessageState, m
}
}
if contact.LastUpdated < message.Clock {
if contact.LastUpdated < message.LastUpdated {
contact.HasAddedUs = message.HasAddedUs
}
if contact.LastUpdatedLocally < message.LastUpdatedLocally {
contact.IsSyncing = true
defer func() {
contact.IsSyncing = false
@ -334,7 +338,7 @@ func (m *Messenger) HandleSyncInstallationContact(state *ReceivedMessageState, m
}
contact.ENSVerified = true
}
contact.LastUpdated = message.Clock
contact.LastUpdatedLocally = message.LastUpdatedLocally
contact.LocalNickname = message.LocalNickname
if message.Blocked != contact.Blocked {

View File

@ -103,8 +103,7 @@ func (s *MessengerInstallationSuite) TestReceiveInstallation() {
contact, err := BuildContactFromPublicKey(&contactKey.PublicKey)
s.Require().NoError(err)
contact.Added = true
err = s.m.SaveContact(contact)
_, err = s.m.AddContact(context.Background(), contact.ID)
s.Require().NoError(err)
// Wait for the message to reach its destination
@ -145,9 +144,10 @@ func (s *MessengerInstallationSuite) TestSyncInstallation() {
contact, err := BuildContactFromPublicKey(&contactKey.PublicKey)
s.Require().NoError(err)
contact.Added = true
contact.LocalNickname = "Test Nickname"
err = s.m.SaveContact(contact)
_, err = s.m.AddContact(context.Background(), contact.ID)
s.Require().NoError(err)
_, err = s.m.SetLocalNickname(contact.ID, contact.LocalNickname)
s.Require().NoError(err)
// add chat
@ -215,7 +215,7 @@ func (s *MessengerInstallationSuite) TestSyncInstallation() {
actualContact = response.Contacts[0]
}
if len(allChats) >= 3 && actualContact != nil {
if len(allChats) >= 2 && actualContact != nil {
return nil
}

View File

@ -39,8 +39,6 @@ const (
testContract = "0x314159265dd8dbb310642f98f50c066173c1259b"
testValue = "2000"
testTransactionHash = "0x412a851ac2ae51cad34a56c8a9cfee55d577ac5e1ac71cf488a2f2093a373799"
testIdenticon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAnElEQVR4nOzXQaqDMBRG4bZkLR10e12H23PgZuJUjJAcE8kdnG/44IXDhZ9iyjm/4vnMDrhmFmEWYRZhFpH6n1jW7fSX/+/b+WbQa5lFmEVUljhqZfSdoNcyizCLeNMvn3JTLeh+g17LLMIsorLElt2VK7v3X0dBr2UWYRaBfxNLfifOZhYRNGvAEp8Q9FpmEWYRZhFmEXsAAAD//5K5JFhu0M0nAAAAAElFTkSuQmCC"
testAlias = "Concrete Lavender Xiphias"
newName = "new-name"
)
@ -256,44 +254,10 @@ func (s *MessengerSuite) TestInit() {
Prep: func() {
key, err := crypto.GenerateKey()
s.Require().NoError(err)
contact := Contact{
ID: types.EncodeHex(crypto.FromECDSAPub(&key.PublicKey)),
Name: "Some Contact",
Added: true,
}
err = s.m.SaveContact(&contact)
_, err = s.m.AddContact(context.Background(), types.EncodeHex(crypto.FromECDSAPub(&key.PublicKey)))
s.Require().NoError(err)
},
AddedFilters: 1,
},
{
Name: "added and blocked contact",
Prep: func() {
key, err := crypto.GenerateKey()
s.Require().NoError(err)
contact := Contact{
ID: types.EncodeHex(crypto.FromECDSAPub(&key.PublicKey)),
Name: "Some Contact",
Blocked: true,
}
err = s.m.SaveContact(&contact)
s.Require().NoError(err)
},
AddedFilters: 0,
},
{
Name: "added by them contact",
Prep: func() {
key, err := crypto.GenerateKey()
s.Require().NoError(err)
contact := Contact{
ID: types.EncodeHex(crypto.FromECDSAPub(&key.PublicKey)),
Name: "Some Contact",
}
err = s.m.SaveContact(&contact)
s.Require().NoError(err)
},
AddedFilters: 0,
AddedFilters: 2,
},
}
@ -747,7 +711,8 @@ func (s *MessengerSuite) TestRetrieveBlockedContact() {
Blocked: true,
}
s.Require().NoError(s.m.SaveContact(&blockedContact))
_, err = s.m.BlockContact(&blockedContact)
s.Require().NoError(err)
inputMessage := buildTestMessage(*chat)
@ -1221,9 +1186,6 @@ func (s *MessengerSuite) TestChatPersistenceOneToOne() {
LastMessage: &common.Message{},
Highlight: false,
}
contact := Contact{
ID: testPK,
}
publicKeyBytes, err := hex.DecodeString(testPK[2:])
s.Require().NoError(err)
@ -1232,7 +1194,6 @@ func (s *MessengerSuite) TestChatPersistenceOneToOne() {
s.Require().NoError(err)
s.Require().NoError(s.m.SaveChat(chat))
s.Require().NoError(s.m.SaveContact(&contact))
savedChats := s.m.Chats()
s.Require().Equal(3, len(savedChats))
@ -1382,7 +1343,8 @@ func (s *MessengerSuite) TestBlockContact() {
s.Require().NoError(s.m.SaveChat(chat2))
s.Require().NoError(s.m.SaveChat(chat3))
s.Require().NoError(s.m.SaveContact(&contact))
_, err := s.m.AddContact(context.Background(), contact.ID)
s.Require().NoError(err)
contact.Name = "blocked"
@ -1464,7 +1426,7 @@ func (s *MessengerSuite) TestBlockContact() {
},
}
err := s.m.SaveMessages(messages)
err = s.m.SaveMessages(messages)
s.Require().NoError(err)
response, err := s.m.BlockContact(&contact)
@ -1511,56 +1473,13 @@ func (s *MessengerSuite) TestBlockContact() {
}
func (s *MessengerSuite) TestContactPersistence() {
contact := Contact{
ID: testPK,
Name: "contact-name",
LastUpdated: 20,
Added: true,
}
s.Require().NoError(s.m.SaveContact(&contact))
_, err := s.m.AddContact(context.Background(), testPK)
s.Require().NoError(err)
savedContacts := s.m.Contacts()
s.Require().Equal(1, len(savedContacts))
actualContact := savedContacts[0]
expectedContact := &contact
expectedContact.Alias = testAlias
expectedContact.Identicon = testIdenticon
s.Require().Equal(expectedContact, actualContact)
}
func (s *MessengerSuite) TestContactPersistenceUpdate() {
contactID := testPK
contact := Contact{
ID: contactID,
Name: "contact-name",
LastUpdated: 20,
Added: true,
}
s.Require().NoError(s.m.SaveContact(&contact))
savedContacts := s.m.Contacts()
s.Require().Equal(1, len(savedContacts))
actualContact := savedContacts[0]
expectedContact := &contact
expectedContact.Alias = testAlias
expectedContact.Identicon = testIdenticon
s.Require().Equal(expectedContact, actualContact)
contact.Name = "updated-name-2"
s.Require().NoError(s.m.SaveContact(&contact))
updatedContact := s.m.Contacts()
s.Require().Equal(1, len(updatedContact))
actualUpdatedContact := updatedContact[0]
expectedUpdatedContact := &contact
s.Require().Equal(expectedUpdatedContact, actualUpdatedContact)
s.Require().True(savedContacts[0].Added)
}
func (s *MessengerSuite) TestSharedSecretHandler() {

View File

@ -46,6 +46,7 @@
// 1632303896_modify_contacts_table.up.sql (1.574kB)
// 1633349838_add_emoji_column_in_chats.up.sql (52B)
// 1634831235_add_highlight_column_in_chats.up.sql (62B)
// 1634896007_add_last_updated_locally_and_removed.up.sql (131B)
// 1635840039_add_clock_read_at_column_in_chats.up.sql (245B)
// README.md (554B)
// doc.go (850B)
@ -1037,6 +1038,26 @@ func _1634831235_add_highlight_column_in_chatsUpSql() (*asset, error) {
return a, nil
}
var __1634896007_add_last_updated_locally_and_removedUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\x48\xce\xcf\x2b\x49\x4c\x2e\x29\x56\x70\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x28\x4a\xcd\xcd\x2f\x4b\x4d\x51\x70\xf2\xf7\xf7\x71\x75\xf4\x53\x70\x71\x75\x73\x0c\xf5\x09\x51\x70\x73\xf4\x09\x76\xb5\xe6\x22\xa4\x3d\x27\xb1\xb8\x24\xbe\xb4\x20\x25\xb1\x24\x35\x25\x3e\x27\x3f\x39\x31\x27\xa7\x52\xc1\xd3\x2f\x04\x6e\x8e\x81\x35\x17\x20\x00\x00\xff\xff\xab\xe8\x7d\xf0\x83\x00\x00\x00")
func _1634896007_add_last_updated_locally_and_removedUpSqlBytes() ([]byte, error) {
return bindataRead(
__1634896007_add_last_updated_locally_and_removedUpSql,
"1634896007_add_last_updated_locally_and_removed.up.sql",
)
}
func _1634896007_add_last_updated_locally_and_removedUpSql() (*asset, error) {
bytes, err := _1634896007_add_last_updated_locally_and_removedUpSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "1634896007_add_last_updated_locally_and_removed.up.sql", size: 131, mode: os.FileMode(0644), modTime: time.Unix(1635867803, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2e, 0xa8, 0x34, 0xe2, 0xc0, 0x62, 0xc8, 0xd6, 0x5a, 0x87, 0xe3, 0x70, 0xe1, 0xc4, 0x16, 0x9c, 0x60, 0x2e, 0x98, 0xf0, 0x91, 0x84, 0xbe, 0xe0, 0xdf, 0x3e, 0x4d, 0x24, 0xc4, 0x6c, 0x40, 0x17}}
return a, nil
}
var __1635840039_add_clock_read_at_column_in_chatsUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\xcc\xc1\x6a\x83\x30\x18\x07\xf0\xbb\x4f\xf1\x3f\x6e\xe0\x61\x77\xd9\x21\x33\x19\x08\x59\x1c\x2e\xc2\x6e\x1f\x21\xf9\x68\xa5\x51\xc1\x68\xe9\xe3\x97\x1c\x2a\xf6\xd2\x07\xf8\xfd\x84\xb6\xaa\x83\x15\x5f\x5a\xc1\x9f\xdd\x9a\x20\xa4\x44\xdd\xea\xfe\xc7\x60\x61\x17\x68\xe4\x94\xdc\x89\x13\xb9\x95\x7c\x9c\xfd\x85\xae\x2e\x6e\x8c\xc6\x58\x48\xf5\x2d\x7a\x6d\xf1\x51\x15\xfd\xaf\x14\xf6\x71\xfc\x29\xfb\x1a\x7f\x66\x52\x77\x2a\x93\xc6\x48\xf5\x8f\x38\x7b\x17\x29\x73\x1a\x02\x25\xe6\x89\x46\x9e\xd6\x61\x9e\x38\x1c\x29\x0d\xe1\x86\xd6\x60\x4b\xbc\xec\xfd\xdb\x93\x2e\x91\x79\x89\xdd\x97\x38\x04\xef\x55\x71\x0f\x00\x00\xff\xff\xab\x82\x7c\xe1\xf5\x00\x00\x00")
func _1635840039_add_clock_read_at_column_in_chatsUpSqlBytes() ([]byte, error) {
@ -1280,6 +1301,8 @@ var _bindata = map[string]func() (*asset, error){
"1634831235_add_highlight_column_in_chats.up.sql": _1634831235_add_highlight_column_in_chatsUpSql,
"1634896007_add_last_updated_locally_and_removed.up.sql": _1634896007_add_last_updated_locally_and_removedUpSql,
"1635840039_add_clock_read_at_column_in_chats.up.sql": _1635840039_add_clock_read_at_column_in_chatsUpSql,
"README.md": readmeMd,
@ -1374,6 +1397,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"1632303896_modify_contacts_table.up.sql": &bintree{_1632303896_modify_contacts_tableUpSql, map[string]*bintree{}},
"1633349838_add_emoji_column_in_chats.up.sql": &bintree{_1633349838_add_emoji_column_in_chatsUpSql, map[string]*bintree{}},
"1634831235_add_highlight_column_in_chats.up.sql": &bintree{_1634831235_add_highlight_column_in_chatsUpSql, map[string]*bintree{}},
"1634896007_add_last_updated_locally_and_removed.up.sql": &bintree{_1634896007_add_last_updated_locally_and_removedUpSql, map[string]*bintree{}},
"1635840039_add_clock_read_at_column_in_chats.up.sql": &bintree{_1635840039_add_clock_read_at_column_in_chatsUpSql, map[string]*bintree{}},
"README.md": &bintree{readmeMd, map[string]*bintree{}},
"doc.go": &bintree{docGo, map[string]*bintree{}},

View File

@ -0,0 +1,2 @@
ALTER TABLE contacts ADD COLUMN removed BOOLEAN DEFAULT FALSE;
ALTER TABLE contacts ADD COLUMN last_updated_locally INT DEFAULT 0;

View File

@ -467,8 +467,10 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
c.alias,
c.identicon,
c.last_updated,
c.last_updated_locally,
c.added,
c.blocked,
c.removed,
c.has_added_us,
c.local_nickname,
i.image_type,
@ -485,15 +487,17 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
for rows.Next() {
var (
contact Contact
nickname sql.NullString
imageType sql.NullString
ensName sql.NullString
ensVerified sql.NullBool
added sql.NullBool
blocked sql.NullBool
hasAddedUs sql.NullBool
imagePayload []byte
contact Contact
nickname sql.NullString
imageType sql.NullString
ensName sql.NullString
ensVerified sql.NullBool
added sql.NullBool
blocked sql.NullBool
removed sql.NullBool
hasAddedUs sql.NullBool
lastUpdatedLocally sql.NullInt64
imagePayload []byte
)
contact.Images = make(map[string]images.IdentityImage)
@ -506,8 +510,10 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
&contact.Alias,
&contact.Identicon,
&contact.LastUpdated,
&lastUpdatedLocally,
&added,
&blocked,
&removed,
&hasAddedUs,
&nickname,
&imageType,
@ -537,6 +543,14 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
contact.Blocked = blocked.Bool
}
if removed.Valid {
contact.Removed = removed.Bool
}
if lastUpdatedLocally.Valid {
contact.LastUpdatedLocally = uint64(lastUpdatedLocally.Int64)
}
if hasAddedUs.Valid {
contact.HasAddedUs = hasAddedUs.Bool
}
@ -678,14 +692,16 @@ func (db sqlitePersistence) SaveContact(contact *Contact, tx *sql.Tx) (err error
alias,
identicon,
last_updated,
last_updated_locally,
local_nickname,
added,
blocked,
removed,
has_added_us,
name,
photo,
tribute_to_talk
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`)
if err != nil {
return
@ -698,9 +714,11 @@ func (db sqlitePersistence) SaveContact(contact *Contact, tx *sql.Tx) (err error
contact.Alias,
contact.Identicon,
contact.LastUpdated,
contact.LastUpdatedLocally,
contact.LocalNickname,
contact.Added,
contact.Blocked,
contact.Removed,
contact.HasAddedUs,
//TODO we need to drop these columns
"",

View File

@ -226,7 +226,7 @@ func (m *SyncInstallationContact) GetLocalNickname() string {
}
type SyncInstallationContactV2 struct {
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
LastUpdatedLocally uint64 `protobuf:"varint,1,opt,name=last_updated_locally,json=lastUpdatedLocally,proto3" json:"last_updated_locally,omitempty"`
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
ProfileImage string `protobuf:"bytes,3,opt,name=profile_image,json=profileImage,proto3" json:"profile_image,omitempty"`
EnsName string `protobuf:"bytes,4,opt,name=ens_name,json=ensName,proto3" json:"ens_name,omitempty"`
@ -237,6 +237,7 @@ type SyncInstallationContactV2 struct {
Blocked bool `protobuf:"varint,10,opt,name=blocked,proto3" json:"blocked,omitempty"`
Muted bool `protobuf:"varint,11,opt,name=muted,proto3" json:"muted,omitempty"`
Removed bool `protobuf:"varint,12,opt,name=removed,proto3" json:"removed,omitempty"`
HasAddedUs bool `protobuf:"varint,13,opt,name=has_added_us,json=hasAddedUs,proto3" json:"has_added_us,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -267,9 +268,9 @@ func (m *SyncInstallationContactV2) XXX_DiscardUnknown() {
var xxx_messageInfo_SyncInstallationContactV2 proto.InternalMessageInfo
func (m *SyncInstallationContactV2) GetClock() uint64 {
func (m *SyncInstallationContactV2) GetLastUpdatedLocally() uint64 {
if m != nil {
return m.Clock
return m.LastUpdatedLocally
}
return 0
}
@ -344,6 +345,13 @@ func (m *SyncInstallationContactV2) GetRemoved() bool {
return false
}
func (m *SyncInstallationContactV2) GetHasAddedUs() bool {
if m != nil {
return m.HasAddedUs
}
return false
}
type SyncInstallationAccount struct {
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
ProfileImage string `protobuf:"bytes,2,opt,name=profile_image,json=profileImage,proto3" json:"profile_image,omitempty"`
@ -804,51 +812,53 @@ func init() {
}
var fileDescriptor_d61ab7221f0b5518 = []byte{
// 725 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x54, 0xcd, 0x6e, 0xdb, 0x38,
0x10, 0x86, 0x64, 0xc7, 0x76, 0xc6, 0x3f, 0x09, 0x88, 0x60, 0xc3, 0x64, 0xb1, 0x88, 0xa3, 0x6c,
0xb0, 0x3e, 0x79, 0x81, 0xec, 0x61, 0x51, 0xa4, 0x45, 0xd1, 0xe4, 0x50, 0xb8, 0x45, 0xd3, 0x40,
0x4d, 0x7b, 0xe8, 0x45, 0xa0, 0x29, 0xc6, 0x61, 0x2d, 0x89, 0xaa, 0x48, 0xb9, 0xf0, 0x0b, 0xf4,
0x01, 0xda, 0xd7, 0x2a, 0xd0, 0xf7, 0xe8, 0x53, 0x14, 0x24, 0x65, 0x45, 0x49, 0xea, 0xc4, 0xe7,
0x9e, 0xa4, 0xf9, 0x38, 0xe4, 0x7c, 0xf3, 0xcd, 0x0f, 0x74, 0x53, 0xc2, 0x33, 0x9e, 0x4c, 0x86,
0x69, 0x26, 0x94, 0x40, 0x2d, 0xf3, 0x19, 0xe7, 0x97, 0x9e, 0x80, 0xc6, 0x09, 0xa1, 0xd3, 0x3c,
0x45, 0x5b, 0xb0, 0x46, 0x23, 0x41, 0xa7, 0xd8, 0xe9, 0x3b, 0x83, 0xba, 0x6f, 0x0d, 0xd4, 0x03,
0x97, 0x87, 0xd8, 0xed, 0x3b, 0x83, 0x75, 0xdf, 0xe5, 0x21, 0x7a, 0x0a, 0x2d, 0x2a, 0x12, 0x45,
0xa8, 0x92, 0xb8, 0xd6, 0xaf, 0x0d, 0xda, 0x47, 0x07, 0xc3, 0xc5, 0x63, 0xc3, 0x37, 0xf3, 0x84,
0x8e, 0x12, 0xa9, 0x48, 0x14, 0x11, 0xc5, 0x45, 0x72, 0x6a, 0x3d, 0xdf, 0x1d, 0xf9, 0xe5, 0x25,
0xef, 0xb3, 0x03, 0x9b, 0xe7, 0x84, 0x67, 0x55, 0xbf, 0x25, 0xb1, 0xff, 0x81, 0x0d, 0x5e, 0xf1,
0x0a, 0x4a, 0x22, 0xbd, 0x2a, 0x3c, 0x0a, 0xd1, 0x1e, 0xb4, 0x43, 0x36, 0xe3, 0x94, 0x05, 0x6a,
0x9e, 0x32, 0x5c, 0x33, 0x4e, 0x60, 0xa1, 0x8b, 0x79, 0xca, 0x10, 0x82, 0x7a, 0x42, 0x62, 0x86,
0xeb, 0xe6, 0xc4, 0xfc, 0x7b, 0x3f, 0x1c, 0xd8, 0x5e, 0x42, 0x78, 0x45, 0x2d, 0x0e, 0xa0, 0x9b,
0x66, 0xe2, 0x92, 0x47, 0x2c, 0xe0, 0x31, 0x99, 0x2c, 0x02, 0x77, 0x0a, 0x70, 0xa4, 0x31, 0xb4,
0x03, 0x2d, 0x96, 0xc8, 0xa0, 0x12, 0xbe, 0xc9, 0x12, 0x79, 0x46, 0x62, 0x86, 0xf6, 0xa1, 0x13,
0x11, 0xa9, 0x82, 0x3c, 0x0d, 0x89, 0x62, 0x21, 0x5e, 0x33, 0xc1, 0xda, 0x1a, 0x7b, 0x6b, 0x21,
0x9d, 0x99, 0x9c, 0x4b, 0xc5, 0xe2, 0x40, 0x91, 0x89, 0xc4, 0x8d, 0x7e, 0x4d, 0x67, 0x66, 0xa1,
0x0b, 0x32, 0x91, 0xe8, 0x10, 0x7a, 0x91, 0xa0, 0x24, 0x0a, 0x12, 0x4e, 0xa7, 0x26, 0x48, 0xd3,
0x04, 0xe9, 0x1a, 0xf4, 0xac, 0x00, 0xbd, 0x6f, 0x2e, 0xec, 0x2c, 0xad, 0xce, 0x6f, 0x97, 0xae,
0x4e, 0x88, 0x84, 0x21, 0x0b, 0xf1, 0x7a, 0xdf, 0x19, 0xb4, 0x7c, 0x6b, 0x20, 0x0c, 0xcd, 0xb1,
0xce, 0x8c, 0x85, 0x18, 0x0c, 0xbe, 0x30, 0xb5, 0x7f, 0x9c, 0x6b, 0x4e, 0x6d, 0xeb, 0x6f, 0x0c,
0xed, 0x9f, 0xb1, 0x58, 0xcc, 0x58, 0x88, 0x3b, 0xd6, 0xbf, 0x30, 0xbd, 0x4f, 0x77, 0x5b, 0xe7,
0x19, 0xa5, 0x22, 0x4f, 0x96, 0xb5, 0xce, 0x1d, 0xed, 0xdc, 0x5f, 0x68, 0x77, 0x5b, 0xa0, 0xda,
0x1d, 0x81, 0xbc, 0x13, 0xd8, 0xbd, 0x1d, 0xf8, 0x3c, 0x1f, 0x47, 0x9c, 0x9e, 0x5e, 0x91, 0x15,
0xdb, 0xd6, 0xfb, 0xea, 0x42, 0x57, 0x3f, 0x72, 0x2a, 0xe2, 0x38, 0x4f, 0xb8, 0x9a, 0x3f, 0x78,
0xaf, 0x63, 0xea, 0xbf, 0x07, 0xed, 0x34, 0xe3, 0x33, 0xa2, 0x58, 0x30, 0x65, 0x73, 0xc3, 0xae,
0xe3, 0x43, 0x01, 0xbd, 0x64, 0x73, 0xd4, 0xd7, 0x63, 0x28, 0x69, 0xc6, 0x53, 0xcd, 0xcb, 0x94,
0xbf, 0xe3, 0x57, 0x21, 0xf4, 0x07, 0x34, 0x3e, 0x08, 0x9e, 0x14, 0xc5, 0x6f, 0xf9, 0x85, 0x85,
0x76, 0xa1, 0x35, 0x63, 0x19, 0xbf, 0xe4, 0x2c, 0xc4, 0x0d, 0x73, 0x52, 0xda, 0xd7, 0xb5, 0x69,
0x56, 0x6b, 0xf3, 0x1a, 0x36, 0x33, 0xf6, 0x31, 0x67, 0x52, 0xc9, 0x40, 0x89, 0x40, 0xbf, 0x83,
0x5b, 0x66, 0x1f, 0x1d, 0xde, 0xdc, 0x47, 0x65, 0x96, 0x7e, 0xe1, 0x7e, 0x21, 0x5e, 0x08, 0x9e,
0xf8, 0xbd, 0xec, 0x86, 0xed, 0x7d, 0x77, 0xe0, 0xcf, 0x7b, 0xfc, 0x0b, 0x35, 0x9c, 0x52, 0x8d,
0xbf, 0x00, 0x52, 0xa3, 0xbc, 0x11, 0xc3, 0xaa, 0xbb, 0x6e, 0x11, 0xad, 0x45, 0x29, 0x69, 0xad,
0x2a, 0xe9, 0x3d, 0xd3, 0xb1, 0x0d, 0x4d, 0x7a, 0x45, 0x94, 0x5e, 0x72, 0x6b, 0xe6, 0xa4, 0xa1,
0xcd, 0x51, 0xa8, 0xbb, 0x82, 0x2e, 0x38, 0xe9, 0xd3, 0x86, 0x95, 0xb5, 0xc4, 0x46, 0x46, 0x22,
0xa9, 0x88, 0xb2, 0xc3, 0x50, 0xf7, 0xad, 0xe1, 0x7d, 0x71, 0x61, 0xf3, 0x76, 0xb3, 0xa0, 0x27,
0x95, 0xfd, 0xed, 0x18, 0xbd, 0xf6, 0x1f, 0xdc, 0xdf, 0xd7, 0xdb, 0x1b, 0x3d, 0x87, 0x4e, 0x91,
0xb5, 0x66, 0x27, 0xb1, 0x6b, 0x9e, 0xf8, 0x7b, 0xf9, 0x13, 0xd7, 0xdd, 0xe9, 0xb7, 0xd3, 0xf2,
0x5f, 0xa2, 0x63, 0x68, 0x12, 0x3b, 0x31, 0x46, 0xa1, 0x7b, 0x69, 0x14, 0xa3, 0xe5, 0x2f, 0x6e,
0xa0, 0x47, 0x50, 0xa6, 0xcf, 0x99, 0xc4, 0x75, 0x43, 0x62, 0x7b, 0x59, 0xdd, 0xab, 0xbe, 0xde,
0xff, 0xb0, 0x61, 0x4e, 0x35, 0x21, 0x3b, 0xcc, 0x2b, 0x4e, 0xcd, 0x63, 0xd8, 0x5a, 0x5c, 0x7c,
0xc5, 0xa4, 0x24, 0x13, 0x26, 0x7d, 0x46, 0x56, 0xbc, 0x7d, 0xd2, 0x7d, 0xdf, 0x1e, 0xfe, 0x7b,
0xbc, 0x20, 0x38, 0x6e, 0x98, 0xbf, 0xff, 0x7e, 0x06, 0x00, 0x00, 0xff, 0xff, 0x54, 0x79, 0x7f,
0x98, 0x97, 0x07, 0x00, 0x00,
// 763 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x54, 0xcd, 0x6e, 0xdb, 0x38,
0x10, 0x86, 0x6c, 0xc7, 0x76, 0xc6, 0xb2, 0x13, 0x10, 0xc1, 0x86, 0xc9, 0x62, 0x11, 0x47, 0xd9,
0x60, 0x7d, 0xf2, 0x2e, 0xb2, 0x87, 0xc5, 0x22, 0xbb, 0x28, 0x92, 0x1c, 0x0a, 0xf7, 0x27, 0x0d,
0xd4, 0xa4, 0x87, 0x5e, 0x04, 0x5a, 0x62, 0x6c, 0xd6, 0x92, 0xa8, 0x8a, 0x94, 0x0b, 0xbd, 0x40,
0x0f, 0x3d, 0xb6, 0x0f, 0xd6, 0xf7, 0xe8, 0x53, 0x14, 0x24, 0x65, 0x45, 0x49, 0xea, 0xc4, 0xd7,
0x9e, 0xa4, 0xf9, 0x66, 0xc8, 0xf9, 0xf8, 0xcd, 0x0f, 0x74, 0x13, 0xc2, 0x52, 0x16, 0x4f, 0x86,
0x49, 0xca, 0x25, 0x47, 0x6d, 0xfd, 0x19, 0x67, 0xd7, 0x0e, 0x87, 0xe6, 0x29, 0xf1, 0x67, 0x59,
0x82, 0xb6, 0x60, 0xcd, 0x0f, 0xb9, 0x3f, 0xc3, 0x56, 0xdf, 0x1a, 0x34, 0x5c, 0x63, 0xa0, 0x1e,
0xd4, 0x58, 0x80, 0x6b, 0x7d, 0x6b, 0xb0, 0xee, 0xd6, 0x58, 0x80, 0x9e, 0x40, 0xdb, 0xe7, 0xb1,
0x24, 0xbe, 0x14, 0xb8, 0xde, 0xaf, 0x0f, 0x3a, 0x47, 0x07, 0xc3, 0xc5, 0x65, 0xc3, 0xd7, 0x79,
0xec, 0x8f, 0x62, 0x21, 0x49, 0x18, 0x12, 0xc9, 0x78, 0x7c, 0x66, 0x22, 0xdf, 0x1c, 0xb9, 0xe5,
0x21, 0xe7, 0xa3, 0x05, 0x9b, 0x17, 0x84, 0xa5, 0xd5, 0xb8, 0x25, 0xb9, 0xff, 0x80, 0x0d, 0x56,
0x89, 0xf2, 0x4a, 0x22, 0xbd, 0x2a, 0x3c, 0x0a, 0xd0, 0x1e, 0x74, 0x02, 0x3a, 0x67, 0x3e, 0xf5,
0x64, 0x9e, 0x50, 0x5c, 0xd7, 0x41, 0x60, 0xa0, 0xcb, 0x3c, 0xa1, 0x08, 0x41, 0x23, 0x26, 0x11,
0xc5, 0x0d, 0xed, 0xd1, 0xff, 0xce, 0x37, 0x0b, 0xb6, 0x97, 0x10, 0x5e, 0x51, 0x8b, 0x03, 0xe8,
0x26, 0x29, 0xbf, 0x66, 0x21, 0xf5, 0x58, 0x44, 0x26, 0x8b, 0xc4, 0x76, 0x01, 0x8e, 0x14, 0x86,
0x76, 0xa0, 0x4d, 0x63, 0xe1, 0x55, 0xd2, 0xb7, 0x68, 0x2c, 0xce, 0x49, 0x44, 0xd1, 0x3e, 0xd8,
0x21, 0x11, 0xd2, 0xcb, 0x92, 0x80, 0x48, 0x1a, 0xe0, 0x35, 0x9d, 0xac, 0xa3, 0xb0, 0x2b, 0x03,
0xa9, 0x97, 0x89, 0x5c, 0x48, 0x1a, 0x79, 0x92, 0x4c, 0x04, 0x6e, 0xf6, 0xeb, 0xea, 0x65, 0x06,
0xba, 0x24, 0x13, 0x81, 0x0e, 0xa1, 0x17, 0x72, 0x9f, 0x84, 0x5e, 0xcc, 0xfc, 0x99, 0x4e, 0xd2,
0xd2, 0x49, 0xba, 0x1a, 0x3d, 0x2f, 0x40, 0xe7, 0x53, 0x1d, 0x76, 0x96, 0x56, 0x07, 0xfd, 0x05,
0x5b, 0x55, 0x22, 0x9e, 0x3e, 0x1b, 0xe6, 0xc5, 0xeb, 0x51, 0x85, 0xd0, 0x0b, 0xe3, 0xf9, 0x89,
0xa5, 0x50, 0xb5, 0x25, 0x41, 0x40, 0x03, 0xbc, 0xde, 0xb7, 0x06, 0x6d, 0xd7, 0x18, 0x08, 0x43,
0x6b, 0xac, 0x8a, 0x4c, 0x03, 0x0c, 0x1a, 0x5f, 0x98, 0x2a, 0x3e, 0xca, 0x14, 0xa7, 0x8e, 0x89,
0xd7, 0x86, 0x8a, 0x4f, 0x69, 0xc4, 0xe7, 0x34, 0xc0, 0xb6, 0x89, 0x2f, 0x4c, 0xd4, 0x07, 0x7b,
0x4a, 0x84, 0xa7, 0xaf, 0xf5, 0x32, 0x81, 0xbb, 0xda, 0x0d, 0x53, 0x22, 0x4e, 0x14, 0x74, 0x25,
0x9c, 0x0f, 0xf7, 0x1b, 0xef, 0xc4, 0xf7, 0x79, 0x16, 0x2f, 0x6b, 0xbc, 0x7b, 0xea, 0xd6, 0x7e,
0xa0, 0xee, 0x5d, 0x09, 0xeb, 0xf7, 0x24, 0x74, 0x4e, 0x61, 0xf7, 0x6e, 0xe2, 0x8b, 0x6c, 0x1c,
0x32, 0xff, 0x6c, 0x4a, 0x56, 0x6c, 0x7a, 0xe7, 0x4b, 0x0d, 0xba, 0xea, 0x92, 0x33, 0x1e, 0x45,
0x59, 0xcc, 0x64, 0xfe, 0xe8, 0x39, 0x5b, 0x77, 0xc8, 0x1e, 0x74, 0x92, 0x94, 0xcd, 0x89, 0xa4,
0xde, 0x8c, 0xe6, 0x9a, 0x9d, 0xed, 0x42, 0x01, 0x3d, 0xa7, 0x39, 0xea, 0xab, 0x21, 0x16, 0x7e,
0xca, 0x12, 0xc5, 0x4b, 0x37, 0x88, 0xed, 0x56, 0x21, 0xf4, 0x0b, 0x34, 0xdf, 0x71, 0x16, 0x17,
0xed, 0xd1, 0x76, 0x0b, 0x0b, 0xed, 0x42, 0x7b, 0x4e, 0x53, 0x76, 0xcd, 0x68, 0x80, 0x9b, 0xda,
0x53, 0xda, 0x37, 0xd5, 0x6b, 0x55, 0xab, 0xf7, 0x0a, 0x36, 0x53, 0xfa, 0x3e, 0xa3, 0x42, 0x0a,
0x4f, 0x72, 0x4f, 0xdd, 0x83, 0xdb, 0x7a, 0x9b, 0x1d, 0xde, 0xde, 0x66, 0xe5, 0x2b, 0xdd, 0x22,
0xfc, 0x92, 0x3f, 0xe3, 0x2c, 0x76, 0x7b, 0xe9, 0x2d, 0xdb, 0xf9, 0x6a, 0xc1, 0xaf, 0x0f, 0xc4,
0x17, 0x6a, 0x58, 0xa5, 0x1a, 0xbf, 0x01, 0x24, 0x5a, 0x79, 0x2d, 0x86, 0x51, 0x77, 0xdd, 0x20,
0x4a, 0x8b, 0x52, 0xd2, 0x7a, 0x55, 0xd2, 0x07, 0xe6, 0x67, 0x1b, 0x5a, 0xfe, 0x94, 0x48, 0xb5,
0x22, 0xd7, 0xb4, 0xa7, 0xa9, 0xcc, 0x51, 0xa0, 0xba, 0xc2, 0x5f, 0x70, 0x52, 0xde, 0xa6, 0x91,
0xb5, 0xc4, 0x46, 0x5a, 0x22, 0x21, 0x89, 0x34, 0xe3, 0xd2, 0x70, 0x8d, 0xe1, 0x7c, 0xae, 0xc1,
0xe6, 0xdd, 0x66, 0x41, 0xff, 0x57, 0xb6, 0xbf, 0xa5, 0xf5, 0xda, 0x7f, 0x74, 0xfb, 0xdf, 0xec,
0x7e, 0xf4, 0x14, 0xec, 0xe2, 0xd5, 0x8a, 0x9d, 0xc0, 0x35, 0x7d, 0xc5, 0xef, 0xcb, 0xaf, 0xb8,
0xe9, 0x4e, 0xb7, 0x93, 0x94, 0xff, 0x02, 0x1d, 0x43, 0x8b, 0x98, 0x89, 0xd1, 0x0a, 0x3d, 0x48,
0xa3, 0x18, 0x2d, 0x77, 0x71, 0x02, 0xfd, 0x0b, 0xe5, 0xf3, 0x19, 0x15, 0xb8, 0xa1, 0x49, 0x6c,
0x2f, 0xab, 0x7b, 0x35, 0xd6, 0xf9, 0x07, 0x36, 0xb4, 0x57, 0x11, 0x2a, 0xc6, 0x7d, 0xb5, 0xa9,
0xf9, 0x0f, 0xb6, 0x16, 0x07, 0x5f, 0x52, 0x21, 0xc8, 0x84, 0x0a, 0x97, 0x92, 0x15, 0x4f, 0x9f,
0x76, 0xdf, 0x76, 0x86, 0x7f, 0x1e, 0x2f, 0x08, 0x8e, 0x9b, 0xfa, 0xef, 0xef, 0xef, 0x01, 0x00,
0x00, 0xff, 0xff, 0x9c, 0x69, 0xcf, 0x28, 0xd5, 0x07, 0x00, 0x00,
}

View File

@ -28,7 +28,7 @@ message SyncInstallationContact {
}
message SyncInstallationContactV2 {
uint64 clock = 1;
uint64 last_updated_locally = 1;
string id = 2;
string profile_image = 3;
string ens_name = 4;
@ -39,6 +39,7 @@ message SyncInstallationContactV2 {
bool blocked = 10;
bool muted = 11;
bool removed = 12;
bool has_added_us = 13;
}
message SyncInstallationAccount {

View File

@ -300,7 +300,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationFromContactO
Added: true,
}
err = bob.SaveContact(aliceContact)
_, err = bob.AddContact(context.Background(), aliceContact.ID)
s.Require().NoError(err)
// Enable from contacts only
@ -446,7 +446,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationRetries() {
Added: true,
}
err = bob.SaveContact(aliceContact)
_, err = bob.AddContact(context.Background(), aliceContact.ID)
s.Require().NoError(err)
// Add frank has a contact
@ -456,7 +456,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationRetries() {
Added: true,
}
err = bob.SaveContact(frankContact)
_, err = bob.AddContact(context.Background(), frankContact.ID)
s.Require().NoError(err)
// Enable from contacts only
@ -542,7 +542,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationRetries() {
ID: types.EncodeHex(crypto.FromECDSAPub(&frank.identity.PublicKey)),
Name: "Some Contact",
}
err = bob.SaveContact(frankContact)
_, err = bob.RemoveContact(context.Background(), frankContact.ID)
s.Require().NoError(err)
// Re-registration should be triggered, pull from server and bob to check we are correctly registered

View File

@ -293,10 +293,6 @@ func (api *PublicAPI) UnmuteChat(parent context.Context, chatID string) error {
return api.service.messenger.UnmuteChat(chatID)
}
func (api *PublicAPI) SaveContact(parent context.Context, contact *protocol.Contact) error {
return api.service.messenger.SaveContact(contact)
}
func (api *PublicAPI) BlockContact(parent context.Context, contact *protocol.Contact) ([]*protocol.Chat, error) {
api.log.Info("blocking contact", "contact", contact.ID)
return api.service.messenger.BlockContact(contact)