Backup removed & added by them contacts
This commit is contained in:
parent
301325a22e
commit
a7b0c6c933
|
@ -185,7 +185,7 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = wakuext.SaveContact(context.Background(), contact)
|
_, err = wakuext.AddContact(context.Background(), contact.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -764,3 +764,15 @@ func (db *Database) SetLastBackup(time uint64) error {
|
||||||
_, err := db.db.Exec("UPDATE settings SET last_backup = ?", time)
|
_, err := db.db.Exec("UPDATE settings SET last_backup = ?", time)
|
||||||
return err
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ var (
|
||||||
DappsAddress: types.HexToAddress("0xD1300f99fDF7346986CbC766903245087394ecd0"),
|
DappsAddress: types.HexToAddress("0xD1300f99fDF7346986CbC766903245087394ecd0"),
|
||||||
InstallationID: "d3efcff6-cffa-560e-a547-21d3858cbc51",
|
InstallationID: "d3efcff6-cffa-560e-a547-21d3858cbc51",
|
||||||
KeyUID: "0x4e8129f3edfc004875be17bf468a784098a9f69b53c095be1f52deff286935ab",
|
KeyUID: "0x4e8129f3edfc004875be17bf468a784098a9f69b53c095be1f52deff286935ab",
|
||||||
|
BackupEnabled: true,
|
||||||
LatestDerivedPath: 0,
|
LatestDerivedPath: 0,
|
||||||
Name: "Jittery Cornflowerblue Kingbird",
|
Name: "Jittery Cornflowerblue Kingbird",
|
||||||
Networks: &networks,
|
Networks: &networks,
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -73,6 +73,9 @@ type Contact struct {
|
||||||
// updates should be discarded if last updated is less than the one stored
|
// updates should be discarded if last updated is less than the one stored
|
||||||
LastUpdated uint64 `json:"lastUpdated"`
|
LastUpdated uint64 `json:"lastUpdated"`
|
||||||
|
|
||||||
|
// LastUpdatedLocally is the last time we updated the contact locally
|
||||||
|
LastUpdatedLocally uint64 `json:"lastUpdatedLocally"`
|
||||||
|
|
||||||
LocalNickname string `json:"localNickname,omitempty"`
|
LocalNickname string `json:"localNickname,omitempty"`
|
||||||
|
|
||||||
Images map[string]images.IdentityImage `json:"images"`
|
Images map[string]images.IdentityImage `json:"images"`
|
||||||
|
|
|
@ -2459,14 +2459,15 @@ func (m *Messenger) syncContact(ctx context.Context, contact *Contact) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
syncMessage := &protobuf.SyncInstallationContactV2{
|
syncMessage := &protobuf.SyncInstallationContactV2{
|
||||||
Clock: clock,
|
LastUpdatedLocally: contact.LastUpdatedLocally,
|
||||||
Id: contact.ID,
|
LastUpdated: contact.LastUpdated,
|
||||||
EnsName: ensName,
|
Id: contact.ID,
|
||||||
LocalNickname: contact.LocalNickname,
|
EnsName: ensName,
|
||||||
Added: contact.Added,
|
LocalNickname: contact.LocalNickname,
|
||||||
Blocked: contact.Blocked,
|
Added: contact.Added,
|
||||||
Muted: muted,
|
Blocked: contact.Blocked,
|
||||||
Removed: contact.Removed,
|
Muted: muted,
|
||||||
|
Removed: contact.Removed,
|
||||||
}
|
}
|
||||||
|
|
||||||
encodedMessage, err := proto.Marshal(syncMessage)
|
encodedMessage, err := proto.Marshal(syncMessage)
|
||||||
|
|
|
@ -68,6 +68,7 @@ func (m *Messenger) startBackupLoop() {
|
||||||
m.logger.Error("failed to backup data", zap.Error(err))
|
m.logger.Error("failed to backup data", zap.Error(err))
|
||||||
}
|
}
|
||||||
case <-m.quit:
|
case <-m.quit:
|
||||||
|
ticker.Stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +136,6 @@ func (m *Messenger) syncBackupContact(ctx context.Context, contact *Contact) *pr
|
||||||
if contact.IsSyncing {
|
if contact.IsSyncing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
clock, _ := m.getLastClockWithRelatedChat()
|
|
||||||
|
|
||||||
var ensName string
|
var ensName string
|
||||||
if contact.ENSVerified {
|
if contact.ENSVerified {
|
||||||
|
@ -149,13 +149,15 @@ func (m *Messenger) syncBackupContact(ctx context.Context, contact *Contact) *pr
|
||||||
}
|
}
|
||||||
|
|
||||||
return &protobuf.SyncInstallationContactV2{
|
return &protobuf.SyncInstallationContactV2{
|
||||||
Clock: clock,
|
LastUpdatedLocally: contact.LastUpdatedLocally,
|
||||||
Id: contact.ID,
|
LastUpdated: contact.LastUpdated,
|
||||||
EnsName: ensName,
|
Id: contact.ID,
|
||||||
LocalNickname: contact.LocalNickname,
|
EnsName: ensName,
|
||||||
Added: contact.Added,
|
LocalNickname: contact.LocalNickname,
|
||||||
Blocked: contact.Blocked,
|
Added: contact.Added,
|
||||||
Muted: muted,
|
Blocked: contact.Blocked,
|
||||||
Removed: contact.Removed,
|
Muted: muted,
|
||||||
|
HasAddedUs: contact.HasAddedUs,
|
||||||
|
Removed: contact.Removed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,3 +186,86 @@ func (s *MessengerBackupSuite) TestBackupContactsGreaterThanBatch() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().Len(bob2.AddedContacts(), BackupContactsPerBatch*2)
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -59,30 +59,36 @@ func (s *MessengerContactUpdateSuite) newMessenger(shh types.Waku) *Messenger {
|
||||||
|
|
||||||
func (s *MessengerContactUpdateSuite) TestReceiveContactUpdate() {
|
func (s *MessengerContactUpdateSuite) TestReceiveContactUpdate() {
|
||||||
theirName := "ens-name.stateofus.eth"
|
theirName := "ens-name.stateofus.eth"
|
||||||
theirPicture := "their-picture"
|
|
||||||
contactID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
|
contactID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
|
||||||
|
|
||||||
theirMessenger := s.newMessenger(s.shh)
|
theirMessenger := s.newMessenger(s.shh)
|
||||||
_, err := theirMessenger.Start()
|
_, err := theirMessenger.Start()
|
||||||
s.Require().NoError(err)
|
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))
|
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().NoError(err)
|
||||||
s.Require().NotNil(response)
|
s.Require().NotNil(response)
|
||||||
|
|
||||||
s.Require().Len(response.Contacts, 1)
|
s.Require().Len(response.Contacts, 1)
|
||||||
contact := response.Contacts[0]
|
contact := response.Contacts[0]
|
||||||
// It should not add the contact, as that's left to `SaveContact`
|
// It should add the contact
|
||||||
s.Require().False(contact.Added)
|
s.Require().True(contact.Added)
|
||||||
|
|
||||||
// add contact
|
// It should create a profile chat & a one to one chat
|
||||||
contact.Added = true
|
s.Require().Len(response.Chats(), 2)
|
||||||
s.Require().NoError(theirMessenger.SaveContact(contact))
|
chats := response.Chats()
|
||||||
|
if chats[0].ChatType == ChatTypeOneToOne {
|
||||||
s.Require().Len(response.Chats(), 1)
|
s.Require().False(chats[0].Active)
|
||||||
chat := response.Chats()[0]
|
} else {
|
||||||
s.Require().False(chat.Active, "It does not create an active chat")
|
s.Require().False(chats[1].Active)
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the message to reach its destination
|
// Wait for the message to reach its destination
|
||||||
response, err = WaitOnMessengerResponse(
|
response, err = WaitOnMessengerResponse(
|
||||||
|
|
|
@ -3,6 +3,7 @@ package protocol
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
||||||
|
@ -11,10 +12,6 @@ import (
|
||||||
"github.com/status-im/status-go/protocol/transport"
|
"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) {
|
func (m *Messenger) AddContact(ctx context.Context, pubKey string) (*MessengerResponse, error) {
|
||||||
contact, ok := m.allContacts.Load(pubKey)
|
contact, ok := m.allContacts.Load(pubKey)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -28,6 +25,7 @@ func (m *Messenger) AddContact(ctx context.Context, pubKey string) (*MessengerRe
|
||||||
if !contact.Added {
|
if !contact.Added {
|
||||||
contact.Added = true
|
contact.Added = true
|
||||||
}
|
}
|
||||||
|
contact.LastUpdatedLocally = m.getTimesource().GetCurrentTime()
|
||||||
|
|
||||||
// We sync the contact with the other devices
|
// We sync the contact with the other devices
|
||||||
err := m.syncContact(context.Background(), contact)
|
err := m.syncContact(context.Background(), contact)
|
||||||
|
@ -63,21 +61,45 @@ func (m *Messenger) AddContact(ctx context.Context, pubKey string) (*MessengerRe
|
||||||
return nil, err
|
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
|
// Finally we send a contact update so they are notified we added them
|
||||||
// TODO: ens and picture are both blank for now
|
ensName, err := m.settings.ENSName()
|
||||||
response, err := m.sendContactUpdate(context.Background(), pubKey, "", "")
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response.AddChat(profileChat)
|
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})
|
_, err = m.transport.InitFilters([]string{profileChat.ID}, []*ecdsa.PublicKey{publicKey})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -106,6 +128,7 @@ func (m *Messenger) removeContact(ctx context.Context, response *MessengerRespon
|
||||||
}
|
}
|
||||||
|
|
||||||
contact.Remove()
|
contact.Remove()
|
||||||
|
contact.LastUpdatedLocally = m.getTimesource().GetCurrentTime()
|
||||||
|
|
||||||
err := m.persistence.SaveContact(contact, nil)
|
err := m.persistence.SaveContact(contact, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -181,8 +204,32 @@ func (m *Messenger) GetContactByID(pubKey string) *Contact {
|
||||||
return 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) {
|
func (m *Messenger) BlockContact(contact *Contact) ([]*Chat, error) {
|
||||||
contact.Block()
|
contact.Block()
|
||||||
|
contact.LastUpdatedLocally = m.getTimesource().GetCurrentTime()
|
||||||
|
|
||||||
chats, err := m.persistence.BlockContact(contact)
|
chats, err := m.persistence.BlockContact(contact)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -208,61 +255,6 @@ func (m *Messenger) BlockContact(contact *Contact) ([]*Chat, error) {
|
||||||
return chats, nil
|
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
|
// Send contact updates to all contacts added by us
|
||||||
func (m *Messenger) SendContactUpdates(ctx context.Context, ensName, profileImage string) (err error) {
|
func (m *Messenger) SendContactUpdates(ctx context.Context, ensName, profileImage string) (err error) {
|
||||||
myID := contactIDFromPublicKey(&m.identity.PublicKey)
|
myID := contactIDFromPublicKey(&m.identity.PublicKey)
|
||||||
|
@ -298,12 +290,8 @@ func (m *Messenger) sendContactUpdate(ctx context.Context, chatID, ensName, prof
|
||||||
var response MessengerResponse
|
var response MessengerResponse
|
||||||
|
|
||||||
contact, ok := m.allContacts.Load(chatID)
|
contact, ok := m.allContacts.Load(chatID)
|
||||||
if !ok {
|
if !ok || !contact.Added {
|
||||||
var err error
|
return nil, nil
|
||||||
contact, err = buildContactFromPkString(chatID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chat, ok := m.allChats.Load(chatID)
|
chat, ok := m.allChats.Load(chatID)
|
||||||
|
@ -348,29 +336,5 @@ func (m *Messenger) sendContactUpdate(ctx context.Context, chatID, ensName, prof
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &response, m.saveContact(contact)
|
return &response, nil
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
contact.IsSyncing = true
|
||||||
defer func() {
|
defer func() {
|
||||||
contact.IsSyncing = false
|
contact.IsSyncing = false
|
||||||
|
@ -334,7 +338,7 @@ func (m *Messenger) HandleSyncInstallationContact(state *ReceivedMessageState, m
|
||||||
}
|
}
|
||||||
contact.ENSVerified = true
|
contact.ENSVerified = true
|
||||||
}
|
}
|
||||||
contact.LastUpdated = message.Clock
|
contact.LastUpdatedLocally = message.LastUpdatedLocally
|
||||||
contact.LocalNickname = message.LocalNickname
|
contact.LocalNickname = message.LocalNickname
|
||||||
|
|
||||||
if message.Blocked != contact.Blocked {
|
if message.Blocked != contact.Blocked {
|
||||||
|
|
|
@ -103,8 +103,7 @@ func (s *MessengerInstallationSuite) TestReceiveInstallation() {
|
||||||
|
|
||||||
contact, err := BuildContactFromPublicKey(&contactKey.PublicKey)
|
contact, err := BuildContactFromPublicKey(&contactKey.PublicKey)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
contact.Added = true
|
_, err = s.m.AddContact(context.Background(), contact.ID)
|
||||||
err = s.m.SaveContact(contact)
|
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// Wait for the message to reach its destination
|
// Wait for the message to reach its destination
|
||||||
|
@ -145,9 +144,10 @@ func (s *MessengerInstallationSuite) TestSyncInstallation() {
|
||||||
|
|
||||||
contact, err := BuildContactFromPublicKey(&contactKey.PublicKey)
|
contact, err := BuildContactFromPublicKey(&contactKey.PublicKey)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
contact.Added = true
|
|
||||||
contact.LocalNickname = "Test Nickname"
|
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)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// add chat
|
// add chat
|
||||||
|
@ -215,7 +215,7 @@ func (s *MessengerInstallationSuite) TestSyncInstallation() {
|
||||||
actualContact = response.Contacts[0]
|
actualContact = response.Contacts[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(allChats) >= 3 && actualContact != nil {
|
if len(allChats) >= 2 && actualContact != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,6 @@ const (
|
||||||
testContract = "0x314159265dd8dbb310642f98f50c066173c1259b"
|
testContract = "0x314159265dd8dbb310642f98f50c066173c1259b"
|
||||||
testValue = "2000"
|
testValue = "2000"
|
||||||
testTransactionHash = "0x412a851ac2ae51cad34a56c8a9cfee55d577ac5e1ac71cf488a2f2093a373799"
|
testTransactionHash = "0x412a851ac2ae51cad34a56c8a9cfee55d577ac5e1ac71cf488a2f2093a373799"
|
||||||
testIdenticon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAnElEQVR4nOzXQaqDMBRG4bZkLR10e12H23PgZuJUjJAcE8kdnG/44IXDhZ9iyjm/4vnMDrhmFmEWYRZhFpH6n1jW7fSX/+/b+WbQa5lFmEVUljhqZfSdoNcyizCLeNMvn3JTLeh+g17LLMIsorLElt2VK7v3X0dBr2UWYRaBfxNLfifOZhYRNGvAEp8Q9FpmEWYRZhFmEXsAAAD//5K5JFhu0M0nAAAAAElFTkSuQmCC"
|
|
||||||
testAlias = "Concrete Lavender Xiphias"
|
|
||||||
newName = "new-name"
|
newName = "new-name"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -256,44 +254,10 @@ func (s *MessengerSuite) TestInit() {
|
||||||
Prep: func() {
|
Prep: func() {
|
||||||
key, err := crypto.GenerateKey()
|
key, err := crypto.GenerateKey()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
contact := Contact{
|
_, err = s.m.AddContact(context.Background(), types.EncodeHex(crypto.FromECDSAPub(&key.PublicKey)))
|
||||||
ID: types.EncodeHex(crypto.FromECDSAPub(&key.PublicKey)),
|
|
||||||
Name: "Some Contact",
|
|
||||||
Added: true,
|
|
||||||
}
|
|
||||||
err = s.m.SaveContact(&contact)
|
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
},
|
},
|
||||||
AddedFilters: 1,
|
AddedFilters: 2,
|
||||||
},
|
|
||||||
{
|
|
||||||
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,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +711,8 @@ func (s *MessengerSuite) TestRetrieveBlockedContact() {
|
||||||
Blocked: true,
|
Blocked: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Require().NoError(s.m.SaveContact(&blockedContact))
|
_, err = s.m.BlockContact(&blockedContact)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
inputMessage := buildTestMessage(*chat)
|
inputMessage := buildTestMessage(*chat)
|
||||||
|
|
||||||
|
@ -1221,9 +1186,6 @@ func (s *MessengerSuite) TestChatPersistenceOneToOne() {
|
||||||
LastMessage: &common.Message{},
|
LastMessage: &common.Message{},
|
||||||
Highlight: false,
|
Highlight: false,
|
||||||
}
|
}
|
||||||
contact := Contact{
|
|
||||||
ID: testPK,
|
|
||||||
}
|
|
||||||
|
|
||||||
publicKeyBytes, err := hex.DecodeString(testPK[2:])
|
publicKeyBytes, err := hex.DecodeString(testPK[2:])
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
@ -1232,7 +1194,6 @@ func (s *MessengerSuite) TestChatPersistenceOneToOne() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
s.Require().NoError(s.m.SaveChat(chat))
|
s.Require().NoError(s.m.SaveChat(chat))
|
||||||
s.Require().NoError(s.m.SaveContact(&contact))
|
|
||||||
savedChats := s.m.Chats()
|
savedChats := s.m.Chats()
|
||||||
s.Require().Equal(3, len(savedChats))
|
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(chat2))
|
||||||
s.Require().NoError(s.m.SaveChat(chat3))
|
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"
|
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)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
response, err := s.m.BlockContact(&contact)
|
response, err := s.m.BlockContact(&contact)
|
||||||
|
@ -1511,56 +1473,13 @@ func (s *MessengerSuite) TestBlockContact() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerSuite) TestContactPersistence() {
|
func (s *MessengerSuite) TestContactPersistence() {
|
||||||
contact := Contact{
|
_, err := s.m.AddContact(context.Background(), testPK)
|
||||||
ID: testPK,
|
s.Require().NoError(err)
|
||||||
|
|
||||||
Name: "contact-name",
|
|
||||||
LastUpdated: 20,
|
|
||||||
Added: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Require().NoError(s.m.SaveContact(&contact))
|
|
||||||
savedContacts := s.m.Contacts()
|
savedContacts := s.m.Contacts()
|
||||||
|
|
||||||
s.Require().Equal(1, len(savedContacts))
|
s.Require().Equal(1, len(savedContacts))
|
||||||
|
|
||||||
actualContact := savedContacts[0]
|
s.Require().True(savedContacts[0].Added)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerSuite) TestSharedSecretHandler() {
|
func (s *MessengerSuite) TestSharedSecretHandler() {
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
// 1632303896_modify_contacts_table.up.sql (1.574kB)
|
// 1632303896_modify_contacts_table.up.sql (1.574kB)
|
||||||
// 1633349838_add_emoji_column_in_chats.up.sql (52B)
|
// 1633349838_add_emoji_column_in_chats.up.sql (52B)
|
||||||
// 1634831235_add_highlight_column_in_chats.up.sql (62B)
|
// 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)
|
// 1635840039_add_clock_read_at_column_in_chats.up.sql (245B)
|
||||||
// README.md (554B)
|
// README.md (554B)
|
||||||
// doc.go (850B)
|
// doc.go (850B)
|
||||||
|
@ -1037,6 +1038,26 @@ func _1634831235_add_highlight_column_in_chatsUpSql() (*asset, error) {
|
||||||
return a, nil
|
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")
|
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) {
|
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,
|
"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,
|
"1635840039_add_clock_read_at_column_in_chats.up.sql": _1635840039_add_clock_read_at_column_in_chatsUpSql,
|
||||||
|
|
||||||
"README.md": readmeMd,
|
"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{}},
|
"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{}},
|
"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{}},
|
"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{}},
|
"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{}},
|
"README.md": &bintree{readmeMd, map[string]*bintree{}},
|
||||||
"doc.go": &bintree{docGo, map[string]*bintree{}},
|
"doc.go": &bintree{docGo, map[string]*bintree{}},
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE contacts ADD COLUMN removed BOOLEAN DEFAULT FALSE;
|
||||||
|
ALTER TABLE contacts ADD COLUMN last_updated_locally INT DEFAULT 0;
|
|
@ -467,8 +467,10 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
|
||||||
c.alias,
|
c.alias,
|
||||||
c.identicon,
|
c.identicon,
|
||||||
c.last_updated,
|
c.last_updated,
|
||||||
|
c.last_updated_locally,
|
||||||
c.added,
|
c.added,
|
||||||
c.blocked,
|
c.blocked,
|
||||||
|
c.removed,
|
||||||
c.has_added_us,
|
c.has_added_us,
|
||||||
c.local_nickname,
|
c.local_nickname,
|
||||||
i.image_type,
|
i.image_type,
|
||||||
|
@ -485,15 +487,17 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
contact Contact
|
contact Contact
|
||||||
nickname sql.NullString
|
nickname sql.NullString
|
||||||
imageType sql.NullString
|
imageType sql.NullString
|
||||||
ensName sql.NullString
|
ensName sql.NullString
|
||||||
ensVerified sql.NullBool
|
ensVerified sql.NullBool
|
||||||
added sql.NullBool
|
added sql.NullBool
|
||||||
blocked sql.NullBool
|
blocked sql.NullBool
|
||||||
hasAddedUs sql.NullBool
|
removed sql.NullBool
|
||||||
imagePayload []byte
|
hasAddedUs sql.NullBool
|
||||||
|
lastUpdatedLocally sql.NullInt64
|
||||||
|
imagePayload []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
contact.Images = make(map[string]images.IdentityImage)
|
contact.Images = make(map[string]images.IdentityImage)
|
||||||
|
@ -506,8 +510,10 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
|
||||||
&contact.Alias,
|
&contact.Alias,
|
||||||
&contact.Identicon,
|
&contact.Identicon,
|
||||||
&contact.LastUpdated,
|
&contact.LastUpdated,
|
||||||
|
&lastUpdatedLocally,
|
||||||
&added,
|
&added,
|
||||||
&blocked,
|
&blocked,
|
||||||
|
&removed,
|
||||||
&hasAddedUs,
|
&hasAddedUs,
|
||||||
&nickname,
|
&nickname,
|
||||||
&imageType,
|
&imageType,
|
||||||
|
@ -537,6 +543,14 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
|
||||||
contact.Blocked = blocked.Bool
|
contact.Blocked = blocked.Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if removed.Valid {
|
||||||
|
contact.Removed = removed.Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
if lastUpdatedLocally.Valid {
|
||||||
|
contact.LastUpdatedLocally = uint64(lastUpdatedLocally.Int64)
|
||||||
|
}
|
||||||
|
|
||||||
if hasAddedUs.Valid {
|
if hasAddedUs.Valid {
|
||||||
contact.HasAddedUs = hasAddedUs.Bool
|
contact.HasAddedUs = hasAddedUs.Bool
|
||||||
}
|
}
|
||||||
|
@ -678,14 +692,16 @@ func (db sqlitePersistence) SaveContact(contact *Contact, tx *sql.Tx) (err error
|
||||||
alias,
|
alias,
|
||||||
identicon,
|
identicon,
|
||||||
last_updated,
|
last_updated,
|
||||||
|
last_updated_locally,
|
||||||
local_nickname,
|
local_nickname,
|
||||||
added,
|
added,
|
||||||
blocked,
|
blocked,
|
||||||
|
removed,
|
||||||
has_added_us,
|
has_added_us,
|
||||||
name,
|
name,
|
||||||
photo,
|
photo,
|
||||||
tribute_to_talk
|
tribute_to_talk
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -698,9 +714,11 @@ func (db sqlitePersistence) SaveContact(contact *Contact, tx *sql.Tx) (err error
|
||||||
contact.Alias,
|
contact.Alias,
|
||||||
contact.Identicon,
|
contact.Identicon,
|
||||||
contact.LastUpdated,
|
contact.LastUpdated,
|
||||||
|
contact.LastUpdatedLocally,
|
||||||
contact.LocalNickname,
|
contact.LocalNickname,
|
||||||
contact.Added,
|
contact.Added,
|
||||||
contact.Blocked,
|
contact.Blocked,
|
||||||
|
contact.Removed,
|
||||||
contact.HasAddedUs,
|
contact.HasAddedUs,
|
||||||
//TODO we need to drop these columns
|
//TODO we need to drop these columns
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -226,7 +226,7 @@ func (m *SyncInstallationContact) GetLocalNickname() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SyncInstallationContactV2 struct {
|
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"`
|
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"`
|
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"`
|
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"`
|
Blocked bool `protobuf:"varint,10,opt,name=blocked,proto3" json:"blocked,omitempty"`
|
||||||
Muted bool `protobuf:"varint,11,opt,name=muted,proto3" json:"muted,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"`
|
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_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -267,9 +268,9 @@ func (m *SyncInstallationContactV2) XXX_DiscardUnknown() {
|
||||||
|
|
||||||
var xxx_messageInfo_SyncInstallationContactV2 proto.InternalMessageInfo
|
var xxx_messageInfo_SyncInstallationContactV2 proto.InternalMessageInfo
|
||||||
|
|
||||||
func (m *SyncInstallationContactV2) GetClock() uint64 {
|
func (m *SyncInstallationContactV2) GetLastUpdatedLocally() uint64 {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Clock
|
return m.LastUpdatedLocally
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -344,6 +345,13 @@ func (m *SyncInstallationContactV2) GetRemoved() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *SyncInstallationContactV2) GetHasAddedUs() bool {
|
||||||
|
if m != nil {
|
||||||
|
return m.HasAddedUs
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type SyncInstallationAccount struct {
|
type SyncInstallationAccount struct {
|
||||||
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
|
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"`
|
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{
|
var fileDescriptor_d61ab7221f0b5518 = []byte{
|
||||||
// 725 bytes of a gzipped FileDescriptorProto
|
// 763 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x54, 0xcd, 0x6e, 0xdb, 0x38,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x54, 0xcd, 0x6e, 0xdb, 0x38,
|
||||||
0x10, 0x86, 0x64, 0xc7, 0x76, 0xc6, 0x3f, 0x09, 0x88, 0x60, 0xc3, 0x64, 0xb1, 0x88, 0xa3, 0x6c,
|
0x10, 0x86, 0x6c, 0xc7, 0x76, 0xc6, 0xb2, 0x13, 0x10, 0xc1, 0x86, 0xc9, 0x62, 0x11, 0x47, 0xd9,
|
||||||
0xb0, 0x3e, 0x79, 0x81, 0xec, 0x61, 0x51, 0xa4, 0x45, 0xd1, 0xe4, 0x50, 0xb8, 0x45, 0xd3, 0x40,
|
0x60, 0x7d, 0xf2, 0x2e, 0xb2, 0x87, 0xc5, 0x22, 0xbb, 0x28, 0x92, 0x1c, 0x0a, 0xf7, 0x27, 0x0d,
|
||||||
0x4d, 0x7b, 0xe8, 0x45, 0xa0, 0x29, 0xc6, 0x61, 0x2d, 0x89, 0xaa, 0x48, 0xb9, 0xf0, 0x0b, 0xf4,
|
0xd4, 0xa4, 0x87, 0x5e, 0x04, 0x5a, 0x62, 0x6c, 0xd6, 0x92, 0xa8, 0x8a, 0x94, 0x0b, 0xbd, 0x40,
|
||||||
0x01, 0xda, 0xd7, 0x2a, 0xd0, 0xf7, 0xe8, 0x53, 0x14, 0x24, 0x65, 0x45, 0x49, 0xea, 0xc4, 0xe7,
|
0x0f, 0x3d, 0xb6, 0x0f, 0xd6, 0xf7, 0xe8, 0x53, 0x14, 0x24, 0x65, 0x45, 0x49, 0xea, 0xc4, 0xd7,
|
||||||
0x9e, 0xa4, 0xf9, 0x38, 0xe4, 0x7c, 0xf3, 0xcd, 0x0f, 0x74, 0x53, 0xc2, 0x33, 0x9e, 0x4c, 0x86,
|
0x9e, 0xa4, 0xf9, 0x66, 0xc8, 0xf9, 0xf8, 0xcd, 0x0f, 0x74, 0x13, 0xc2, 0x52, 0x16, 0x4f, 0x86,
|
||||||
0x69, 0x26, 0x94, 0x40, 0x2d, 0xf3, 0x19, 0xe7, 0x97, 0x9e, 0x80, 0xc6, 0x09, 0xa1, 0xd3, 0x3c,
|
0x49, 0xca, 0x25, 0x47, 0x6d, 0xfd, 0x19, 0x67, 0xd7, 0x0e, 0x87, 0xe6, 0x29, 0xf1, 0x67, 0x59,
|
||||||
0x45, 0x5b, 0xb0, 0x46, 0x23, 0x41, 0xa7, 0xd8, 0xe9, 0x3b, 0x83, 0xba, 0x6f, 0x0d, 0xd4, 0x03,
|
0x82, 0xb6, 0x60, 0xcd, 0x0f, 0xb9, 0x3f, 0xc3, 0x56, 0xdf, 0x1a, 0x34, 0x5c, 0x63, 0xa0, 0x1e,
|
||||||
0x97, 0x87, 0xd8, 0xed, 0x3b, 0x83, 0x75, 0xdf, 0xe5, 0x21, 0x7a, 0x0a, 0x2d, 0x2a, 0x12, 0x45,
|
0xd4, 0x58, 0x80, 0x6b, 0x7d, 0x6b, 0xb0, 0xee, 0xd6, 0x58, 0x80, 0x9e, 0x40, 0xdb, 0xe7, 0xb1,
|
||||||
0xa8, 0x92, 0xb8, 0xd6, 0xaf, 0x0d, 0xda, 0x47, 0x07, 0xc3, 0xc5, 0x63, 0xc3, 0x37, 0xf3, 0x84,
|
0x24, 0xbe, 0x14, 0xb8, 0xde, 0xaf, 0x0f, 0x3a, 0x47, 0x07, 0xc3, 0xc5, 0x65, 0xc3, 0xd7, 0x79,
|
||||||
0x8e, 0x12, 0xa9, 0x48, 0x14, 0x11, 0xc5, 0x45, 0x72, 0x6a, 0x3d, 0xdf, 0x1d, 0xf9, 0xe5, 0x25,
|
0xec, 0x8f, 0x62, 0x21, 0x49, 0x18, 0x12, 0xc9, 0x78, 0x7c, 0x66, 0x22, 0xdf, 0x1c, 0xb9, 0xe5,
|
||||||
0xef, 0xb3, 0x03, 0x9b, 0xe7, 0x84, 0x67, 0x55, 0xbf, 0x25, 0xb1, 0xff, 0x81, 0x0d, 0x5e, 0xf1,
|
0x21, 0xe7, 0xa3, 0x05, 0x9b, 0x17, 0x84, 0xa5, 0xd5, 0xb8, 0x25, 0xb9, 0xff, 0x80, 0x0d, 0x56,
|
||||||
0x0a, 0x4a, 0x22, 0xbd, 0x2a, 0x3c, 0x0a, 0xd1, 0x1e, 0xb4, 0x43, 0x36, 0xe3, 0x94, 0x05, 0x6a,
|
0x89, 0xf2, 0x4a, 0x22, 0xbd, 0x2a, 0x3c, 0x0a, 0xd0, 0x1e, 0x74, 0x02, 0x3a, 0x67, 0x3e, 0xf5,
|
||||||
0x9e, 0x32, 0x5c, 0x33, 0x4e, 0x60, 0xa1, 0x8b, 0x79, 0xca, 0x10, 0x82, 0x7a, 0x42, 0x62, 0x86,
|
0x64, 0x9e, 0x50, 0x5c, 0xd7, 0x41, 0x60, 0xa0, 0xcb, 0x3c, 0xa1, 0x08, 0x41, 0x23, 0x26, 0x11,
|
||||||
0xeb, 0xe6, 0xc4, 0xfc, 0x7b, 0x3f, 0x1c, 0xd8, 0x5e, 0x42, 0x78, 0x45, 0x2d, 0x0e, 0xa0, 0x9b,
|
0xc5, 0x0d, 0xed, 0xd1, 0xff, 0xce, 0x37, 0x0b, 0xb6, 0x97, 0x10, 0x5e, 0x51, 0x8b, 0x03, 0xe8,
|
||||||
0x66, 0xe2, 0x92, 0x47, 0x2c, 0xe0, 0x31, 0x99, 0x2c, 0x02, 0x77, 0x0a, 0x70, 0xa4, 0x31, 0xb4,
|
0x26, 0x29, 0xbf, 0x66, 0x21, 0xf5, 0x58, 0x44, 0x26, 0x8b, 0xc4, 0x76, 0x01, 0x8e, 0x14, 0x86,
|
||||||
0x03, 0x2d, 0x96, 0xc8, 0xa0, 0x12, 0xbe, 0xc9, 0x12, 0x79, 0x46, 0x62, 0x86, 0xf6, 0xa1, 0x13,
|
0x76, 0xa0, 0x4d, 0x63, 0xe1, 0x55, 0xd2, 0xb7, 0x68, 0x2c, 0xce, 0x49, 0x44, 0xd1, 0x3e, 0xd8,
|
||||||
0x11, 0xa9, 0x82, 0x3c, 0x0d, 0x89, 0x62, 0x21, 0x5e, 0x33, 0xc1, 0xda, 0x1a, 0x7b, 0x6b, 0x21,
|
0x21, 0x11, 0xd2, 0xcb, 0x92, 0x80, 0x48, 0x1a, 0xe0, 0x35, 0x9d, 0xac, 0xa3, 0xb0, 0x2b, 0x03,
|
||||||
0x9d, 0x99, 0x9c, 0x4b, 0xc5, 0xe2, 0x40, 0x91, 0x89, 0xc4, 0x8d, 0x7e, 0x4d, 0x67, 0x66, 0xa1,
|
0xa9, 0x97, 0x89, 0x5c, 0x48, 0x1a, 0x79, 0x92, 0x4c, 0x04, 0x6e, 0xf6, 0xeb, 0xea, 0x65, 0x06,
|
||||||
0x0b, 0x32, 0x91, 0xe8, 0x10, 0x7a, 0x91, 0xa0, 0x24, 0x0a, 0x12, 0x4e, 0xa7, 0x26, 0x48, 0xd3,
|
0xba, 0x24, 0x13, 0x81, 0x0e, 0xa1, 0x17, 0x72, 0x9f, 0x84, 0x5e, 0xcc, 0xfc, 0x99, 0x4e, 0xd2,
|
||||||
0x04, 0xe9, 0x1a, 0xf4, 0xac, 0x00, 0xbd, 0x6f, 0x2e, 0xec, 0x2c, 0xad, 0xce, 0x6f, 0x97, 0xae,
|
0xd2, 0x49, 0xba, 0x1a, 0x3d, 0x2f, 0x40, 0xe7, 0x53, 0x1d, 0x76, 0x96, 0x56, 0x07, 0xfd, 0x05,
|
||||||
0x4e, 0x88, 0x84, 0x21, 0x0b, 0xf1, 0x7a, 0xdf, 0x19, 0xb4, 0x7c, 0x6b, 0x20, 0x0c, 0xcd, 0xb1,
|
0x5b, 0x55, 0x22, 0x9e, 0x3e, 0x1b, 0xe6, 0xc5, 0xeb, 0x51, 0x85, 0xd0, 0x0b, 0xe3, 0xf9, 0x89,
|
||||||
0xce, 0x8c, 0x85, 0x18, 0x0c, 0xbe, 0x30, 0xb5, 0x7f, 0x9c, 0x6b, 0x4e, 0x6d, 0xeb, 0x6f, 0x0c,
|
0xa5, 0x50, 0xb5, 0x25, 0x41, 0x40, 0x03, 0xbc, 0xde, 0xb7, 0x06, 0x6d, 0xd7, 0x18, 0x08, 0x43,
|
||||||
0xed, 0x9f, 0xb1, 0x58, 0xcc, 0x58, 0x88, 0x3b, 0xd6, 0xbf, 0x30, 0xbd, 0x4f, 0x77, 0x5b, 0xe7,
|
0x6b, 0xac, 0x8a, 0x4c, 0x03, 0x0c, 0x1a, 0x5f, 0x98, 0x2a, 0x3e, 0xca, 0x14, 0xa7, 0x8e, 0x89,
|
||||||
0x19, 0xa5, 0x22, 0x4f, 0x96, 0xb5, 0xce, 0x1d, 0xed, 0xdc, 0x5f, 0x68, 0x77, 0x5b, 0xa0, 0xda,
|
0xd7, 0x86, 0x8a, 0x4f, 0x69, 0xc4, 0xe7, 0x34, 0xc0, 0xb6, 0x89, 0x2f, 0x4c, 0xd4, 0x07, 0x7b,
|
||||||
0x1d, 0x81, 0xbc, 0x13, 0xd8, 0xbd, 0x1d, 0xf8, 0x3c, 0x1f, 0x47, 0x9c, 0x9e, 0x5e, 0x91, 0x15,
|
0x4a, 0x84, 0xa7, 0xaf, 0xf5, 0x32, 0x81, 0xbb, 0xda, 0x0d, 0x53, 0x22, 0x4e, 0x14, 0x74, 0x25,
|
||||||
0xdb, 0xd6, 0xfb, 0xea, 0x42, 0x57, 0x3f, 0x72, 0x2a, 0xe2, 0x38, 0x4f, 0xb8, 0x9a, 0x3f, 0x78,
|
0x9c, 0x0f, 0xf7, 0x1b, 0xef, 0xc4, 0xf7, 0x79, 0x16, 0x2f, 0x6b, 0xbc, 0x7b, 0xea, 0xd6, 0x7e,
|
||||||
0xaf, 0x63, 0xea, 0xbf, 0x07, 0xed, 0x34, 0xe3, 0x33, 0xa2, 0x58, 0x30, 0x65, 0x73, 0xc3, 0xae,
|
0xa0, 0xee, 0x5d, 0x09, 0xeb, 0xf7, 0x24, 0x74, 0x4e, 0x61, 0xf7, 0x6e, 0xe2, 0x8b, 0x6c, 0x1c,
|
||||||
0xe3, 0x43, 0x01, 0xbd, 0x64, 0x73, 0xd4, 0xd7, 0x63, 0x28, 0x69, 0xc6, 0x53, 0xcd, 0xcb, 0x94,
|
0x32, 0xff, 0x6c, 0x4a, 0x56, 0x6c, 0x7a, 0xe7, 0x4b, 0x0d, 0xba, 0xea, 0x92, 0x33, 0x1e, 0x45,
|
||||||
0xbf, 0xe3, 0x57, 0x21, 0xf4, 0x07, 0x34, 0x3e, 0x08, 0x9e, 0x14, 0xc5, 0x6f, 0xf9, 0x85, 0x85,
|
0x59, 0xcc, 0x64, 0xfe, 0xe8, 0x39, 0x5b, 0x77, 0xc8, 0x1e, 0x74, 0x92, 0x94, 0xcd, 0x89, 0xa4,
|
||||||
0x76, 0xa1, 0x35, 0x63, 0x19, 0xbf, 0xe4, 0x2c, 0xc4, 0x0d, 0x73, 0x52, 0xda, 0xd7, 0xb5, 0x69,
|
0xde, 0x8c, 0xe6, 0x9a, 0x9d, 0xed, 0x42, 0x01, 0x3d, 0xa7, 0x39, 0xea, 0xab, 0x21, 0x16, 0x7e,
|
||||||
0x56, 0x6b, 0xf3, 0x1a, 0x36, 0x33, 0xf6, 0x31, 0x67, 0x52, 0xc9, 0x40, 0x89, 0x40, 0xbf, 0x83,
|
0xca, 0x12, 0xc5, 0x4b, 0x37, 0x88, 0xed, 0x56, 0x21, 0xf4, 0x0b, 0x34, 0xdf, 0x71, 0x16, 0x17,
|
||||||
0x5b, 0x66, 0x1f, 0x1d, 0xde, 0xdc, 0x47, 0x65, 0x96, 0x7e, 0xe1, 0x7e, 0x21, 0x5e, 0x08, 0x9e,
|
0xed, 0xd1, 0x76, 0x0b, 0x0b, 0xed, 0x42, 0x7b, 0x4e, 0x53, 0x76, 0xcd, 0x68, 0x80, 0x9b, 0xda,
|
||||||
0xf8, 0xbd, 0xec, 0x86, 0xed, 0x7d, 0x77, 0xe0, 0xcf, 0x7b, 0xfc, 0x0b, 0x35, 0x9c, 0x52, 0x8d,
|
0x53, 0xda, 0x37, 0xd5, 0x6b, 0x55, 0xab, 0xf7, 0x0a, 0x36, 0x53, 0xfa, 0x3e, 0xa3, 0x42, 0x0a,
|
||||||
0xbf, 0x00, 0x52, 0xa3, 0xbc, 0x11, 0xc3, 0xaa, 0xbb, 0x6e, 0x11, 0xad, 0x45, 0x29, 0x69, 0xad,
|
0x4f, 0x72, 0x4f, 0xdd, 0x83, 0xdb, 0x7a, 0x9b, 0x1d, 0xde, 0xde, 0x66, 0xe5, 0x2b, 0xdd, 0x22,
|
||||||
0x2a, 0xe9, 0x3d, 0xd3, 0xb1, 0x0d, 0x4d, 0x7a, 0x45, 0x94, 0x5e, 0x72, 0x6b, 0xe6, 0xa4, 0xa1,
|
0xfc, 0x92, 0x3f, 0xe3, 0x2c, 0x76, 0x7b, 0xe9, 0x2d, 0xdb, 0xf9, 0x6a, 0xc1, 0xaf, 0x0f, 0xc4,
|
||||||
0xcd, 0x51, 0xa8, 0xbb, 0x82, 0x2e, 0x38, 0xe9, 0xd3, 0x86, 0x95, 0xb5, 0xc4, 0x46, 0x46, 0x22,
|
0x17, 0x6a, 0x58, 0xa5, 0x1a, 0xbf, 0x01, 0x24, 0x5a, 0x79, 0x2d, 0x86, 0x51, 0x77, 0xdd, 0x20,
|
||||||
0xa9, 0x88, 0xb2, 0xc3, 0x50, 0xf7, 0xad, 0xe1, 0x7d, 0x71, 0x61, 0xf3, 0x76, 0xb3, 0xa0, 0x27,
|
0x4a, 0x8b, 0x52, 0xd2, 0x7a, 0x55, 0xd2, 0x07, 0xe6, 0x67, 0x1b, 0x5a, 0xfe, 0x94, 0x48, 0xb5,
|
||||||
0x95, 0xfd, 0xed, 0x18, 0xbd, 0xf6, 0x1f, 0xdc, 0xdf, 0xd7, 0xdb, 0x1b, 0x3d, 0x87, 0x4e, 0x91,
|
0x22, 0xd7, 0xb4, 0xa7, 0xa9, 0xcc, 0x51, 0xa0, 0xba, 0xc2, 0x5f, 0x70, 0x52, 0xde, 0xa6, 0x91,
|
||||||
0xb5, 0x66, 0x27, 0xb1, 0x6b, 0x9e, 0xf8, 0x7b, 0xf9, 0x13, 0xd7, 0xdd, 0xe9, 0xb7, 0xd3, 0xf2,
|
0xb5, 0xc4, 0x46, 0x5a, 0x22, 0x21, 0x89, 0x34, 0xe3, 0xd2, 0x70, 0x8d, 0xe1, 0x7c, 0xae, 0xc1,
|
||||||
0x5f, 0xa2, 0x63, 0x68, 0x12, 0x3b, 0x31, 0x46, 0xa1, 0x7b, 0x69, 0x14, 0xa3, 0xe5, 0x2f, 0x6e,
|
0xe6, 0xdd, 0x66, 0x41, 0xff, 0x57, 0xb6, 0xbf, 0xa5, 0xf5, 0xda, 0x7f, 0x74, 0xfb, 0xdf, 0xec,
|
||||||
0xa0, 0x47, 0x50, 0xa6, 0xcf, 0x99, 0xc4, 0x75, 0x43, 0x62, 0x7b, 0x59, 0xdd, 0xab, 0xbe, 0xde,
|
0x7e, 0xf4, 0x14, 0xec, 0xe2, 0xd5, 0x8a, 0x9d, 0xc0, 0x35, 0x7d, 0xc5, 0xef, 0xcb, 0xaf, 0xb8,
|
||||||
0xff, 0xb0, 0x61, 0x4e, 0x35, 0x21, 0x3b, 0xcc, 0x2b, 0x4e, 0xcd, 0x63, 0xd8, 0x5a, 0x5c, 0x7c,
|
0xe9, 0x4e, 0xb7, 0x93, 0x94, 0xff, 0x02, 0x1d, 0x43, 0x8b, 0x98, 0x89, 0xd1, 0x0a, 0x3d, 0x48,
|
||||||
0xc5, 0xa4, 0x24, 0x13, 0x26, 0x7d, 0x46, 0x56, 0xbc, 0x7d, 0xd2, 0x7d, 0xdf, 0x1e, 0xfe, 0x7b,
|
0xa3, 0x18, 0x2d, 0x77, 0x71, 0x02, 0xfd, 0x0b, 0xe5, 0xf3, 0x19, 0x15, 0xb8, 0xa1, 0x49, 0x6c,
|
||||||
0xbc, 0x20, 0x38, 0x6e, 0x98, 0xbf, 0xff, 0x7e, 0x06, 0x00, 0x00, 0xff, 0xff, 0x54, 0x79, 0x7f,
|
0x2f, 0xab, 0x7b, 0x35, 0xd6, 0xf9, 0x07, 0x36, 0xb4, 0x57, 0x11, 0x2a, 0xc6, 0x7d, 0xb5, 0xa9,
|
||||||
0x98, 0x97, 0x07, 0x00, 0x00,
|
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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ message SyncInstallationContact {
|
||||||
}
|
}
|
||||||
|
|
||||||
message SyncInstallationContactV2 {
|
message SyncInstallationContactV2 {
|
||||||
uint64 clock = 1;
|
uint64 last_updated_locally = 1;
|
||||||
string id = 2;
|
string id = 2;
|
||||||
string profile_image = 3;
|
string profile_image = 3;
|
||||||
string ens_name = 4;
|
string ens_name = 4;
|
||||||
|
@ -39,6 +39,7 @@ message SyncInstallationContactV2 {
|
||||||
bool blocked = 10;
|
bool blocked = 10;
|
||||||
bool muted = 11;
|
bool muted = 11;
|
||||||
bool removed = 12;
|
bool removed = 12;
|
||||||
|
bool has_added_us = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SyncInstallationAccount {
|
message SyncInstallationAccount {
|
||||||
|
|
|
@ -300,7 +300,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationFromContactO
|
||||||
Added: true,
|
Added: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bob.SaveContact(aliceContact)
|
_, err = bob.AddContact(context.Background(), aliceContact.ID)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// Enable from contacts only
|
// Enable from contacts only
|
||||||
|
@ -446,7 +446,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationRetries() {
|
||||||
Added: true,
|
Added: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bob.SaveContact(aliceContact)
|
_, err = bob.AddContact(context.Background(), aliceContact.ID)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// Add frank has a contact
|
// Add frank has a contact
|
||||||
|
@ -456,7 +456,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationRetries() {
|
||||||
Added: true,
|
Added: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bob.SaveContact(frankContact)
|
_, err = bob.AddContact(context.Background(), frankContact.ID)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// Enable from contacts only
|
// Enable from contacts only
|
||||||
|
@ -542,7 +542,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationRetries() {
|
||||||
ID: types.EncodeHex(crypto.FromECDSAPub(&frank.identity.PublicKey)),
|
ID: types.EncodeHex(crypto.FromECDSAPub(&frank.identity.PublicKey)),
|
||||||
Name: "Some Contact",
|
Name: "Some Contact",
|
||||||
}
|
}
|
||||||
err = bob.SaveContact(frankContact)
|
_, err = bob.RemoveContact(context.Background(), frankContact.ID)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// Re-registration should be triggered, pull from server and bob to check we are correctly registered
|
// Re-registration should be triggered, pull from server and bob to check we are correctly registered
|
||||||
|
|
|
@ -293,10 +293,6 @@ func (api *PublicAPI) UnmuteChat(parent context.Context, chatID string) error {
|
||||||
return api.service.messenger.UnmuteChat(chatID)
|
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) {
|
func (api *PublicAPI) BlockContact(parent context.Context, contact *protocol.Contact) ([]*protocol.Chat, error) {
|
||||||
api.log.Info("blocking contact", "contact", contact.ID)
|
api.log.Info("blocking contact", "contact", contact.ID)
|
||||||
return api.service.messenger.BlockContact(contact)
|
return api.service.messenger.BlockContact(contact)
|
||||||
|
|
Loading…
Reference in New Issue