diff --git a/VERSION b/VERSION index 455e4b308..a60f2152e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.142.5 +0.142.6 diff --git a/account/json/utils.go b/account/json/utils.go index 10b9f571a..f8699165c 100644 --- a/account/json/utils.go +++ b/account/json/utils.go @@ -28,6 +28,11 @@ func getPubKeyData(publicKey string) (*PublicKeyData, error) { } func ExtendStructWithPubKeyData(publicKey string, item any) (any, error) { + // If the public key is empty, do not attempt to extend the incoming item + if publicKey == "" { + return item, nil + } + pkd, err := getPubKeyData(publicKey) if err != nil { return nil, err diff --git a/multiaccounts/settings/structs.go b/multiaccounts/settings/structs.go index 111a30183..ef2233168 100644 --- a/multiaccounts/settings/structs.go +++ b/multiaccounts/settings/structs.go @@ -2,6 +2,7 @@ package settings import ( "encoding/json" + "reflect" accountJson "github.com/status-im/status-go/account/json" "github.com/status-im/status-go/eth-node/types" @@ -200,3 +201,8 @@ func (s Settings) MarshalJSON() ([]byte, error) { } return json.Marshal(ext) } + +func (s Settings) IsEmpty() bool { + empty := reflect.Zero(reflect.TypeOf(s)).Interface() + return reflect.DeepEqual(s, empty) +} diff --git a/server/pairing/client.go b/server/pairing/client.go index e3e4df4dc..a04aeac45 100644 --- a/server/pairing/client.go +++ b/server/pairing/client.go @@ -111,7 +111,7 @@ type SenderClient struct { *BaseClient accountMounter PayloadMounter rawMessageMounter PayloadMounter - installationMounter *InstallationPayloadMounterReceiver + installationMounter PayloadMounterReceiver } // NewSenderClient returns a fully qualified SenderClient created with the incoming parameters @@ -284,8 +284,8 @@ type ReceiverClient struct { *BaseClient accountReceiver PayloadReceiver - rawMessageReceiver *RawMessagePayloadReceiver - installationReceiver *InstallationPayloadMounterReceiver + rawMessageReceiver PayloadReceiver + installationReceiver PayloadMounterReceiver } // NewReceiverClient returns a fully qualified ReceiverClient created with the incoming parameters diff --git a/server/pairing/interfaces.go b/server/pairing/interfaces.go index 90a28c605..d2f332291 100644 --- a/server/pairing/interfaces.go +++ b/server/pairing/interfaces.go @@ -25,6 +25,10 @@ type PayloadLocker interface { LockPayload() } +// TODO if this interface only gets a logger, then maybe remove the interface and change consuming function params +// to accept a *zap.logger +// https://github.com/status-im/status-go/issues/3370 + type HandlerServer interface { GetLogger() *zap.Logger } diff --git a/server/pairing/payload_encryptor.go b/server/pairing/payload_encryptor.go index 127febc76..bd0d2f54c 100644 --- a/server/pairing/payload_encryptor.go +++ b/server/pairing/payload_encryptor.go @@ -17,9 +17,6 @@ func (ep *EncryptionPayload) lock() { ep.locked = true } -// TODO resolve the many cases of other structs simply wrapping their encryptor rather than embedding the functionality -// https://github.com/status-im/status-go/issues/3302 - // PayloadEncryptor is responsible for encrypting and decrypting payload data type PayloadEncryptor struct { aesKey []byte @@ -93,6 +90,7 @@ func (pem *PayloadEncryptor) lockPayload() { pem.payload.lock() } +// PayloadLockPayload Embeds a *PayloadEncryptor to give all embedding structs EncryptionPayload Locking type PayloadLockPayload struct { *PayloadEncryptor } @@ -101,6 +99,8 @@ func (pl *PayloadLockPayload) LockPayload() { pl.lockPayload() } +// PayloadToSend Embeds a *PayloadEncryptor to give all embedding structs EncryptionPayload ToSend() functionality +// Useful to securely implement the PayloadMounter interface type PayloadToSend struct { *PayloadEncryptor } @@ -109,6 +109,8 @@ func (pts *PayloadToSend) ToSend() []byte { return pts.getEncrypted() } +// PayloadReceived Embeds a *PayloadEncryptor to give all embedding structs EncryptionPayload Received() functionality +// Useful to securely implement the PayloadReceiver interface type PayloadReceived struct { *PayloadEncryptor } diff --git a/server/pairing/payload_management.go b/server/pairing/payload_management.go index d59aa2c57..a607953ff 100644 --- a/server/pairing/payload_management.go +++ b/server/pairing/payload_management.go @@ -1,6 +1,7 @@ package pairing import ( + "encoding/json" "errors" "github.com/golang/protobuf/proto" @@ -8,15 +9,14 @@ import ( "github.com/status-im/status-go/api" "github.com/status-im/status-go/multiaccounts" + "github.com/status-im/status-go/multiaccounts/accounts" + "github.com/status-im/status-go/multiaccounts/settings" "github.com/status-im/status-go/protocol/protobuf" ) const keystoreDir = "keystore" var ( - // TODO add validation on config to ensure required fields have valid values - // https://github.com/status-im/status-go/issues/3303 - ErrKeyFileAlreadyExists = errors.New("key file already exists") ErrKeyUIDEmptyAsSender = errors.New("keyUID must be provided as sender") ErrNodeConfigNilAsReceiver = errors.New("node config must be provided as receiver") @@ -103,36 +103,86 @@ func (ppm *AccountPayloadMarshaller) multiaccountFromProtobuf(pbMultiAccount *pr ppm.multiaccount.FromProtobuf(pbMultiAccount) } -// RawMessagePayloadMarshaller is responsible for marshalling and unmarshalling raw message data -type RawMessagePayloadMarshaller struct { - payload *protobuf.SyncRawMessage +type RawMessagesPayload struct { + rawMessages []*protobuf.RawMessage + subAccounts []*accounts.Account + setting *settings.Settings } -func NewRawMessagePayloadMarshaller(payload *protobuf.SyncRawMessage) *RawMessagePayloadMarshaller { +func NewRawMessagesPayload() *RawMessagesPayload { + return &RawMessagesPayload{ + setting: new(settings.Settings), + } +} + +// RawMessagePayloadMarshaller is responsible for marshalling and unmarshalling raw message data +type RawMessagePayloadMarshaller struct { + payload *RawMessagesPayload +} + +func NewRawMessagePayloadMarshaller(payload *RawMessagesPayload) *RawMessagePayloadMarshaller { return &RawMessagePayloadMarshaller{ payload: payload, } } -func (rmm *RawMessagePayloadMarshaller) MarshalProtobuf() ([]byte, error) { - return proto.Marshal(rmm.payload) +func (rmm *RawMessagePayloadMarshaller) MarshalProtobuf() (data []byte, err error) { + syncRawMessage := new(protobuf.SyncRawMessage) + + syncRawMessage.RawMessages = rmm.payload.rawMessages + if len(rmm.payload.subAccounts) > 0 { + syncRawMessage.SubAccountsJsonBytes, err = json.Marshal(rmm.payload.subAccounts) + if err != nil { + return nil, err + } + } + if !rmm.payload.setting.IsEmpty() { + syncRawMessage.SettingsJsonBytes, err = json.Marshal(rmm.payload.setting) + if err != nil { + return nil, err + } + } + + return proto.Marshal(syncRawMessage) +} + +func (rmm *RawMessagePayloadMarshaller) UnmarshalProtobuf(data []byte) error { + syncRawMessage := new(protobuf.SyncRawMessage) + err := proto.Unmarshal(data, syncRawMessage) + if err != nil { + return err + } + if syncRawMessage.SubAccountsJsonBytes != nil { + err = json.Unmarshal(syncRawMessage.SubAccountsJsonBytes, &rmm.payload.subAccounts) + if err != nil { + return err + } + } + if syncRawMessage.SettingsJsonBytes != nil { + err = json.Unmarshal(syncRawMessage.SettingsJsonBytes, rmm.payload.setting) + if err != nil { + return err + } + } + + rmm.payload.rawMessages = syncRawMessage.RawMessages + return nil } // InstallationPayloadMounterReceiver represents an InstallationPayload Repository type InstallationPayloadMounterReceiver struct { PayloadMounter - *InstallationPayloadReceiver + PayloadReceiver } -func NewInstallationPayloadMounterReceiver(logger *zap.Logger, encryptor *PayloadEncryptor, backend *api.GethStatusBackend, deviceType string) *InstallationPayloadMounterReceiver { - l := logger.Named("InstallationPayloadMounterReceiver") +func NewInstallationPayloadMounterReceiver(encryptor *PayloadEncryptor, backend *api.GethStatusBackend, deviceType string) *InstallationPayloadMounterReceiver { return &InstallationPayloadMounterReceiver{ - NewInstallationPayloadMounter(l, encryptor, backend, deviceType), - NewInstallationPayloadReceiver(l, encryptor, backend, deviceType), + NewInstallationPayloadMounter(encryptor, backend, deviceType), + NewInstallationPayloadReceiver(encryptor, backend, deviceType), } } func (i *InstallationPayloadMounterReceiver) LockPayload() { i.PayloadMounter.LockPayload() - i.InstallationPayloadReceiver.LockPayload() + i.PayloadReceiver.LockPayload() } diff --git a/server/pairing/payload_mounter.go b/server/pairing/payload_mounter.go index b8b58d2df..db87d0234 100644 --- a/server/pairing/payload_mounter.go +++ b/server/pairing/payload_mounter.go @@ -5,7 +5,6 @@ import ( "github.com/status-im/status-go/api" "github.com/status-im/status-go/multiaccounts" - "github.com/status-im/status-go/protocol/protobuf" ) type PayloadMounter interface { @@ -26,29 +25,29 @@ type BasePayloadMounter struct { *PayloadLockPayload *PayloadToSend - payloadLoader PayloadLoader - payloadMarshaller ProtobufMarshaller - encryptor *PayloadEncryptor + loader PayloadLoader + marshaller ProtobufMarshaller + encryptor *PayloadEncryptor } func NewBasePayloadMounter(loader PayloadLoader, marshaller ProtobufMarshaller, e *PayloadEncryptor) *BasePayloadMounter { return &BasePayloadMounter{ PayloadLockPayload: &PayloadLockPayload{e}, PayloadToSend: &PayloadToSend{e}, - payloadLoader: loader, - payloadMarshaller: marshaller, + loader: loader, + marshaller: marshaller, encryptor: e, } } // Mount loads and prepares the payload to be stored in the PayloadLoader's state ready for later access func (bpm *BasePayloadMounter) Mount() error { - err := bpm.payloadLoader.Load() + err := bpm.loader.Load() if err != nil { return err } - p, err := bpm.payloadMarshaller.MarshalProtobuf() + p, err := bpm.marshaller.MarshalProtobuf() if err != nil { return err } @@ -65,7 +64,7 @@ func (bpm *BasePayloadMounter) Mount() error { | */ -// NewAccountPayloadMounter generates a new and initialised AccountPayloadMounter +// NewAccountPayloadMounter generates a new and initialised AccountPayload flavoured BasePayloadMounter // responsible for the whole lifecycle of an AccountPayload func NewAccountPayloadMounter(pe *PayloadEncryptor, config *SenderConfig, logger *zap.Logger) (*BasePayloadMounter, error) { l := logger.Named("AccountPayloadLoader") @@ -141,11 +140,11 @@ func (apl *AccountPayloadLoader) Load() error { | */ -// NewRawMessagePayloadMounter generates a new and initialised RawMessagePayloadMounter +// NewRawMessagePayloadMounter generates a new and initialised RawMessagePayload flavoured BasePayloadMounter // responsible for the whole lifecycle of an RawMessagePayload func NewRawMessagePayloadMounter(logger *zap.Logger, pe *PayloadEncryptor, backend *api.GethStatusBackend, config *SenderConfig) *BasePayloadMounter { pe = pe.Renew() - payload := new(protobuf.SyncRawMessage) + payload := NewRawMessagesPayload() return NewBasePayloadMounter( NewRawMessageLoader(backend, payload, config), @@ -155,13 +154,13 @@ func NewRawMessagePayloadMounter(logger *zap.Logger, pe *PayloadEncryptor, backe } type RawMessageLoader struct { - payload *protobuf.SyncRawMessage + payload *RawMessagesPayload syncRawMessageHandler *SyncRawMessageHandler keyUID string deviceType string } -func NewRawMessageLoader(backend *api.GethStatusBackend, payload *protobuf.SyncRawMessage, config *SenderConfig) *RawMessageLoader { +func NewRawMessageLoader(backend *api.GethStatusBackend, payload *RawMessagesPayload, config *SenderConfig) *RawMessageLoader { return &RawMessageLoader{ syncRawMessageHandler: NewSyncRawMessageHandler(backend), payload: payload, @@ -171,7 +170,7 @@ func NewRawMessageLoader(backend *api.GethStatusBackend, payload *protobuf.SyncR } func (r *RawMessageLoader) Load() (err error) { - *r.payload, err = r.syncRawMessageHandler.PrepareRawMessage(r.keyUID, r.deviceType) + r.payload.rawMessages, r.payload.subAccounts, r.payload.setting, err = r.syncRawMessageHandler.PrepareRawMessage(r.keyUID, r.deviceType) return err } @@ -184,11 +183,11 @@ func (r *RawMessageLoader) Load() (err error) { | */ -// NewInstallationPayloadMounter generates a new and initialised InstallationPayloadMounter +// NewInstallationPayloadMounter generates a new and initialised InstallationPayload flavoured BasePayloadMounter // responsible for the whole lifecycle of an InstallationPayload -func NewInstallationPayloadMounter(logger *zap.Logger, pe *PayloadEncryptor, backend *api.GethStatusBackend, deviceType string) *BasePayloadMounter { +func NewInstallationPayloadMounter(pe *PayloadEncryptor, backend *api.GethStatusBackend, deviceType string) *BasePayloadMounter { pe = pe.Renew() - payload := new(protobuf.SyncRawMessage) + payload := NewRawMessagesPayload() return NewBasePayloadMounter( NewInstallationPayloadLoader(backend, payload, deviceType), @@ -198,12 +197,12 @@ func NewInstallationPayloadMounter(logger *zap.Logger, pe *PayloadEncryptor, bac } type InstallationPayloadLoader struct { - payload *protobuf.SyncRawMessage + payload *RawMessagesPayload syncRawMessageHandler *SyncRawMessageHandler deviceType string } -func NewInstallationPayloadLoader(backend *api.GethStatusBackend, payload *protobuf.SyncRawMessage, deviceType string) *InstallationPayloadLoader { +func NewInstallationPayloadLoader(backend *api.GethStatusBackend, payload *RawMessagesPayload, deviceType string) *InstallationPayloadLoader { return &InstallationPayloadLoader{ payload: payload, syncRawMessageHandler: NewSyncRawMessageHandler(backend), @@ -217,7 +216,8 @@ func (r *InstallationPayloadLoader) Load() error { if err != nil { return err } - *r.payload = rawMessageCollector.convertToSyncRawMessage() + rms := rawMessageCollector.convertToSyncRawMessage() + r.payload.rawMessages = rms.RawMessages return nil } @@ -232,12 +232,12 @@ func (r *InstallationPayloadLoader) Load() error { // NewPayloadMounters returns PayloadMounter s configured to handle local pairing transfers of: // - AccountPayload, RawMessagePayload and InstallationPayload -func NewPayloadMounters(logger *zap.Logger, pe *PayloadEncryptor, backend *api.GethStatusBackend, config *SenderConfig) (PayloadMounter, PayloadMounter, *InstallationPayloadMounterReceiver, error) { +func NewPayloadMounters(logger *zap.Logger, pe *PayloadEncryptor, backend *api.GethStatusBackend, config *SenderConfig) (PayloadMounter, PayloadMounter, PayloadMounterReceiver, error) { am, err := NewAccountPayloadMounter(pe, config, logger) if err != nil { return nil, nil, nil, err } rmm := NewRawMessagePayloadMounter(logger, pe, backend, config) - imr := NewInstallationPayloadMounterReceiver(logger, pe, backend, config.DeviceType) + imr := NewInstallationPayloadMounterReceiver(pe, backend, config.DeviceType) return am, rmm, imr, nil } diff --git a/server/pairing/payload_receiver.go b/server/pairing/payload_receiver.go index a1a2900e2..c5fa30605 100644 --- a/server/pairing/payload_receiver.go +++ b/server/pairing/payload_receiver.go @@ -32,15 +32,44 @@ type PayloadStorer interface { type BasePayloadReceiver struct { *PayloadLockPayload *PayloadReceived + + encryptor *PayloadEncryptor + unmarshaller ProtobufUnmarshaller + storer PayloadStorer + + receiveCallback func() } -func NewBaseBasePayloadReceiver(e *PayloadEncryptor) *BasePayloadReceiver { +func NewBaseBasePayloadReceiver(e *PayloadEncryptor, um ProtobufUnmarshaller, s PayloadStorer, callback func()) *BasePayloadReceiver { return &BasePayloadReceiver{ - &PayloadLockPayload{e}, - &PayloadReceived{e}, + PayloadLockPayload: &PayloadLockPayload{e}, + PayloadReceived: &PayloadReceived{e}, + encryptor: e, + unmarshaller: um, + storer: s, + receiveCallback: callback, } } +// Receive takes a []byte representing raw data, parses and stores the data +func (bpr *BasePayloadReceiver) Receive(data []byte) error { + err := bpr.encryptor.decrypt(data) + if err != nil { + return err + } + + err = bpr.unmarshaller.UnmarshalProtobuf(bpr.Received()) + if err != nil { + return err + } + + if bpr.receiveCallback != nil { + bpr.receiveCallback() + } + + return bpr.storer.Store() +} + /* |-------------------------------------------------------------------------- | AccountPayload @@ -50,56 +79,24 @@ func NewBaseBasePayloadReceiver(e *PayloadEncryptor) *BasePayloadReceiver { | */ -// AccountPayloadReceiver is responsible for the whole lifecycle of a AccountPayload -type AccountPayloadReceiver struct { - *BasePayloadReceiver - - logger *zap.Logger - accountPayload *AccountPayload - encryptor *PayloadEncryptor - accountPayloadMarshaller *AccountPayloadMarshaller - accountStorer *AccountPayloadStorer -} - -// NewAccountPayloadReceiver generates a new and initialised AccountPayloadManager -func NewAccountPayloadReceiver(e *PayloadEncryptor, config *ReceiverConfig, logger *zap.Logger) (*AccountPayloadReceiver, error) { +// NewAccountPayloadReceiver generates a new and initialised AccountPayload flavoured BasePayloadReceiver +// AccountPayloadReceiver is responsible for the whole receive and store cycle of an AccountPayload +func NewAccountPayloadReceiver(e *PayloadEncryptor, p *AccountPayload, config *ReceiverConfig, logger *zap.Logger) (*BasePayloadReceiver, error) { l := logger.Named("AccountPayloadManager") l.Debug("fired", zap.Any("config", config)) e = e.Renew() - // A new SHARED AccountPayload - p := new(AccountPayload) - accountPayloadRepository, err := NewAccountPayloadStorer(p, config) + aps, err := NewAccountPayloadStorer(p, config) if err != nil { return nil, err } - return &AccountPayloadReceiver{ - BasePayloadReceiver: NewBaseBasePayloadReceiver(e), - logger: l, - accountPayload: p, - encryptor: e, - accountPayloadMarshaller: NewPairingPayloadMarshaller(p, l), - accountStorer: accountPayloadRepository, - }, nil -} - -// Receive takes a []byte representing raw data, parses and stores the data -func (apr *AccountPayloadReceiver) Receive(data []byte) error { - err := apr.encryptor.decrypt(data) - if err != nil { - return err - } - - err = apr.accountPayloadMarshaller.UnmarshalProtobuf(apr.Received()) - if err != nil { - return err - } - - signal.SendLocalPairingEvent(Event{Type: EventReceivedAccount, Action: ActionPairingAccount, Data: apr.accountPayload.multiaccount}) - - return apr.accountStorer.Store() + return NewBaseBasePayloadReceiver(e, NewPairingPayloadMarshaller(p, l), aps, + func() { + signal.SendLocalPairingEvent(Event{Type: EventReceivedAccount, Action: ActionPairingAccount, Data: p.multiaccount}) + }, + ), nil } // AccountPayloadStorer is responsible for parsing, validating and storing AccountPayload data @@ -217,38 +214,19 @@ func (aps *AccountPayloadStorer) storeMultiAccount() error { | */ -type RawMessagePayloadReceiver struct { - *BasePayloadReceiver - - logger *zap.Logger - encryptor *PayloadEncryptor - storer *RawMessageStorer -} - -func NewRawMessagePayloadReceiver(logger *zap.Logger, accountPayload *AccountPayload, e *PayloadEncryptor, backend *api.GethStatusBackend, config *ReceiverConfig) *RawMessagePayloadReceiver { - l := logger.Named("RawMessagePayloadManager") - +// NewRawMessagePayloadReceiver generates a new and initialised RawMessagesPayload flavoured BasePayloadReceiver +// RawMessagePayloadReceiver is responsible for the whole receive and store cycle of a RawMessagesPayload +func NewRawMessagePayloadReceiver(accountPayload *AccountPayload, e *PayloadEncryptor, backend *api.GethStatusBackend, config *ReceiverConfig) *BasePayloadReceiver { e = e.Renew() + payload := NewRawMessagesPayload() - return &RawMessagePayloadReceiver{ - BasePayloadReceiver: NewBaseBasePayloadReceiver(e), - logger: l, - encryptor: e, - storer: NewRawMessageStorer(backend, accountPayload, config), - } -} - -func (r *RawMessagePayloadReceiver) Receive(data []byte) error { - err := r.encryptor.decrypt(data) - if err != nil { - return err - } - r.storer.payload = r.Received() - return r.storer.Store() + return NewBaseBasePayloadReceiver(e, + NewRawMessagePayloadMarshaller(payload), + NewRawMessageStorer(backend, payload, accountPayload, config), nil) } type RawMessageStorer struct { - payload []byte + payload *RawMessagesPayload syncRawMessageHandler *SyncRawMessageHandler accountPayload *AccountPayload nodeConfig *params.NodeConfig @@ -256,10 +234,10 @@ type RawMessageStorer struct { deviceType string } -func NewRawMessageStorer(backend *api.GethStatusBackend, accountPayload *AccountPayload, config *ReceiverConfig) *RawMessageStorer { +func NewRawMessageStorer(backend *api.GethStatusBackend, payload *RawMessagesPayload, accountPayload *AccountPayload, config *ReceiverConfig) *RawMessageStorer { return &RawMessageStorer{ syncRawMessageHandler: NewSyncRawMessageHandler(backend), - payload: make([]byte, 0), + payload: payload, accountPayload: accountPayload, nodeConfig: config.NodeConfig, settingCurrentNetwork: config.SettingCurrentNetwork, @@ -268,11 +246,10 @@ func NewRawMessageStorer(backend *api.GethStatusBackend, accountPayload *Account } func (r *RawMessageStorer) Store() error { - accountPayload := r.accountPayload - if accountPayload == nil || accountPayload.multiaccount == nil { + if r.accountPayload == nil || r.accountPayload.multiaccount == nil { return fmt.Errorf("no known multiaccount when storing raw messages") } - return r.syncRawMessageHandler.HandleRawMessage(accountPayload, r.nodeConfig, r.settingCurrentNetwork, r.deviceType, r.payload) + return r.syncRawMessageHandler.HandleRawMessage(r.accountPayload, r.nodeConfig, r.settingCurrentNetwork, r.deviceType, r.payload) } /* @@ -284,45 +261,28 @@ func (r *RawMessageStorer) Store() error { | */ -type InstallationPayloadReceiver struct { - *BasePayloadReceiver - - logger *zap.Logger - encryptor *PayloadEncryptor - storer *InstallationPayloadStorer -} - -func NewInstallationPayloadReceiver(logger *zap.Logger, e *PayloadEncryptor, backend *api.GethStatusBackend, deviceType string) *InstallationPayloadReceiver { - l := logger.Named("InstallationPayloadManager") - +// NewInstallationPayloadReceiver generates a new and initialised InstallationPayload flavoured BasePayloadReceiver +// InstallationPayloadReceiver is responsible for the whole receive and store cycle of a RawMessagesPayload specifically +// for sending / requesting installation data from the Receiver device. +func NewInstallationPayloadReceiver(e *PayloadEncryptor, backend *api.GethStatusBackend, deviceType string) *BasePayloadReceiver { e = e.Renew() + payload := NewRawMessagesPayload() - return &InstallationPayloadReceiver{ - BasePayloadReceiver: NewBaseBasePayloadReceiver(e), - logger: l, - encryptor: e, - storer: NewInstallationPayloadStorer(backend, deviceType), - } -} - -func (i *InstallationPayloadReceiver) Receive(data []byte) error { - err := i.encryptor.decrypt(data) - if err != nil { - return err - } - i.storer.payload = i.encryptor.getDecrypted() - return i.storer.Store() + return NewBaseBasePayloadReceiver(e, + NewRawMessagePayloadMarshaller(payload), + NewInstallationPayloadStorer(backend, payload, deviceType), nil) } type InstallationPayloadStorer struct { - payload []byte + payload *RawMessagesPayload syncRawMessageHandler *SyncRawMessageHandler deviceType string backend *api.GethStatusBackend } -func NewInstallationPayloadStorer(backend *api.GethStatusBackend, deviceType string) *InstallationPayloadStorer { +func NewInstallationPayloadStorer(backend *api.GethStatusBackend, payload *RawMessagesPayload, deviceType string) *InstallationPayloadStorer { return &InstallationPayloadStorer{ + payload: payload, syncRawMessageHandler: NewSyncRawMessageHandler(backend), deviceType: deviceType, backend: backend, @@ -334,15 +294,11 @@ func (r *InstallationPayloadStorer) Store() error { if messenger == nil { return fmt.Errorf("messenger is nil when invoke InstallationPayloadRepository#Store()") } - rawMessages, _, _, err := r.syncRawMessageHandler.unmarshalSyncRawMessage(r.payload) + err := messenger.SetInstallationDeviceType(r.deviceType) if err != nil { return err } - err = messenger.SetInstallationDeviceType(r.deviceType) - if err != nil { - return err - } - return messenger.HandleSyncRawMessages(rawMessages) + return messenger.HandleSyncRawMessages(r.payload.rawMessages) } /* @@ -354,12 +310,15 @@ func (r *InstallationPayloadStorer) Store() error { | */ -func NewPayloadReceivers(logger *zap.Logger, pe *PayloadEncryptor, backend *api.GethStatusBackend, config *ReceiverConfig) (*AccountPayloadReceiver, *RawMessagePayloadReceiver, *InstallationPayloadMounterReceiver, error) { - ar, err := NewAccountPayloadReceiver(pe, config, logger) +func NewPayloadReceivers(logger *zap.Logger, pe *PayloadEncryptor, backend *api.GethStatusBackend, config *ReceiverConfig) (PayloadReceiver, PayloadReceiver, PayloadMounterReceiver, error) { + // A new SHARED AccountPayload + p := new(AccountPayload) + + ar, err := NewAccountPayloadReceiver(pe, p, config, logger) if err != nil { return nil, nil, nil, err } - rmr := NewRawMessagePayloadReceiver(logger, ar.accountPayload, pe, backend, config) - imr := NewInstallationPayloadMounterReceiver(logger, pe, backend, config.DeviceType) + rmr := NewRawMessagePayloadReceiver(p, pe, backend, config) + imr := NewInstallationPayloadMounterReceiver(pe, backend, config.DeviceType) return ar, rmr, imr, nil } diff --git a/server/pairing/raw_message_collector.go b/server/pairing/raw_message_collector.go index a203e180d..ce2ec8a68 100644 --- a/server/pairing/raw_message_collector.go +++ b/server/pairing/raw_message_collector.go @@ -21,7 +21,7 @@ func (r *RawMessageCollector) getRawMessages() []*common.RawMessage { return r.rawMessages } -func (r *RawMessageCollector) convertToSyncRawMessage() protobuf.SyncRawMessage { +func (r *RawMessageCollector) convertToSyncRawMessage() *protobuf.SyncRawMessage { syncRawMessage := new(protobuf.SyncRawMessage) for _, m := range r.getRawMessages() { rawMessage := new(protobuf.RawMessage) @@ -29,5 +29,5 @@ func (r *RawMessageCollector) convertToSyncRawMessage() protobuf.SyncRawMessage rawMessage.MessageType = m.MessageType syncRawMessage.RawMessages = append(syncRawMessage.RawMessages, rawMessage) } - return *syncRawMessage + return syncRawMessage } diff --git a/server/pairing/raw_message_handler.go b/server/pairing/raw_message_handler.go index 919386130..081005ec3 100644 --- a/server/pairing/raw_message_handler.go +++ b/server/pairing/raw_message_handler.go @@ -2,12 +2,9 @@ package pairing import ( "context" - "encoding/json" "fmt" "path/filepath" - "github.com/golang/protobuf/proto" - "github.com/status-im/status-go/api" "github.com/status-im/status-go/multiaccounts/accounts" "github.com/status-im/status-go/multiaccounts/settings" @@ -38,10 +35,11 @@ func (s *SyncRawMessageHandler) CollectInstallationData(rawMessageCollector *Raw return err } -func (s *SyncRawMessageHandler) PrepareRawMessage(keyUID, deviceType string) (rsm protobuf.SyncRawMessage, err error) { +func (s *SyncRawMessageHandler) PrepareRawMessage(keyUID, deviceType string) (rm []*protobuf.RawMessage, as []*accounts.Account, syncSettings *settings.Settings, err error) { + syncSettings = new(settings.Settings) messenger := s.backend.Messenger() if messenger == nil { - return rsm, fmt.Errorf("messenger is nil when PrepareRawMessage") + return nil, nil, nil, fmt.Errorf("messenger is nil when PrepareRawMessage") } currentAccount, err := s.backend.GetActiveAccount() @@ -49,7 +47,7 @@ func (s *SyncRawMessageHandler) PrepareRawMessage(keyUID, deviceType string) (rs return } if keyUID != currentAccount.KeyUID { - return rsm, fmt.Errorf("keyUID not equal") + return nil, nil, nil, fmt.Errorf("keyUID not equal") } messenger.SetLocalPairing(true) @@ -67,26 +65,16 @@ func (s *SyncRawMessageHandler) PrepareRawMessage(keyUID, deviceType string) (rs return } - rsm = rawMessageCollector.convertToSyncRawMessage() + rsm := rawMessageCollector.convertToSyncRawMessage() + rm = rsm.RawMessages accountService := s.backend.StatusNode().AccountService() - var ( - subAccounts []*accounts.Account - setting settings.Settings - ) - subAccounts, err = accountService.GetAccountsByKeyUID(keyUID) + + as, err = accountService.GetAccountsByKeyUID(keyUID) if err != nil { return } - rsm.SubAccountsJsonBytes, err = json.Marshal(subAccounts) - if err != nil { - return - } - setting, err = accountService.GetSettings() - if err != nil { - return - } - rsm.SettingsJsonBytes, err = json.Marshal(setting) + *syncSettings, err = accountService.GetSettings() if err != nil { return } @@ -94,12 +82,8 @@ func (s *SyncRawMessageHandler) PrepareRawMessage(keyUID, deviceType string) (rs return } -func (s *SyncRawMessageHandler) HandleRawMessage(accountPayload *AccountPayload, nodeConfig *params.NodeConfig, settingCurrentNetwork, deviceType string, rawMessagePayload []byte) error { +func (s *SyncRawMessageHandler) HandleRawMessage(accountPayload *AccountPayload, nodeConfig *params.NodeConfig, settingCurrentNetwork, deviceType string, rmp *RawMessagesPayload) (err error) { account := accountPayload.multiaccount - rawMessages, subAccounts, setting, err := s.unmarshalSyncRawMessage(rawMessagePayload) - if err != nil { - return err - } activeAccount, _ := s.backend.GetActiveAccount() if activeAccount == nil { // not login yet @@ -115,10 +99,10 @@ func (s *SyncRawMessageHandler) HandleRawMessage(accountPayload *AccountPayload, if err != nil { return err } - setting.InstallationID = nodeConfig.ShhextConfig.InstallationID - setting.CurrentNetwork = settingCurrentNetwork + rmp.setting.InstallationID = nodeConfig.ShhextConfig.InstallationID + rmp.setting.CurrentNetwork = settingCurrentNetwork - err = s.backend.StartNodeWithAccountAndInitialConfig(*account, accountPayload.password, *setting, nodeConfig, subAccounts) + err = s.backend.StartNodeWithAccountAndInitialConfig(*account, accountPayload.password, *rmp.setting, nodeConfig, rmp.subAccounts) } if err != nil { return err @@ -133,30 +117,5 @@ func (s *SyncRawMessageHandler) HandleRawMessage(accountPayload *AccountPayload, if err != nil { return err } - return messenger.HandleSyncRawMessages(rawMessages) -} - -func (s *SyncRawMessageHandler) unmarshalSyncRawMessage(payload []byte) ([]*protobuf.RawMessage, []*accounts.Account, *settings.Settings, error) { - var ( - syncRawMessage protobuf.SyncRawMessage - subAccounts []*accounts.Account - setting *settings.Settings - ) - err := proto.Unmarshal(payload, &syncRawMessage) - if err != nil { - return nil, nil, nil, err - } - if syncRawMessage.SubAccountsJsonBytes != nil { - err = json.Unmarshal(syncRawMessage.SubAccountsJsonBytes, &subAccounts) - if err != nil { - return nil, nil, nil, err - } - } - if syncRawMessage.SettingsJsonBytes != nil { - err = json.Unmarshal(syncRawMessage.SettingsJsonBytes, &setting) - if err != nil { - return nil, nil, nil, err - } - } - return syncRawMessage.RawMessages, subAccounts, setting, nil + return messenger.HandleSyncRawMessages(rmp.rawMessages) } diff --git a/server/pairing/server.go b/server/pairing/server.go index ab7b1009f..99e1e4206 100644 --- a/server/pairing/server.go +++ b/server/pairing/server.go @@ -113,7 +113,7 @@ type SenderServer struct { *BaseServer accountMounter PayloadMounter rawMessageMounter PayloadMounter - installationMounter *InstallationPayloadMounterReceiver + installationMounter PayloadMounterReceiver } // NewSenderServer returns a *SenderServer init from the given *SenderServerConfig diff --git a/server/pairing/sync_device_test.go b/server/pairing/sync_device_test.go index 99b90a11b..d11a1bcec 100644 --- a/server/pairing/sync_device_test.go +++ b/server/pairing/sync_device_test.go @@ -326,33 +326,33 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsReceiver() { func defaultSettings(generatedAccountInfo generator.GeneratedAccountInfo, derivedAddresses map[string]generator.AccountInfo, mnemonic *string) (*settings.Settings, error) { chatKeyString := derivedAddresses[pathDefaultChat].PublicKey - settings := &settings.Settings{} - settings.KeyUID = generatedAccountInfo.KeyUID - settings.Address = types.HexToAddress(generatedAccountInfo.Address) - settings.WalletRootAddress = types.HexToAddress(derivedAddresses[pathWalletRoot].Address) + syncSettings := &settings.Settings{} + syncSettings.KeyUID = generatedAccountInfo.KeyUID + syncSettings.Address = types.HexToAddress(generatedAccountInfo.Address) + syncSettings.WalletRootAddress = types.HexToAddress(derivedAddresses[pathWalletRoot].Address) // Set chat key & name name, err := alias.GenerateFromPublicKeyString(chatKeyString) if err != nil { return nil, err } - settings.Name = name - settings.PublicKey = chatKeyString + syncSettings.Name = name + syncSettings.PublicKey = chatKeyString - settings.DappsAddress = types.HexToAddress(derivedAddresses[pathDefaultWallet].Address) - settings.EIP1581Address = types.HexToAddress(derivedAddresses[pathEIP1581].Address) - settings.Mnemonic = mnemonic + syncSettings.DappsAddress = types.HexToAddress(derivedAddresses[pathDefaultWallet].Address) + syncSettings.EIP1581Address = types.HexToAddress(derivedAddresses[pathEIP1581].Address) + syncSettings.Mnemonic = mnemonic - settings.SigningPhrase = "balabala" + syncSettings.SigningPhrase = "balabala" - settings.SendPushNotifications = true - settings.InstallationID = uuid.New().String() - settings.UseMailservers = true + syncSettings.SendPushNotifications = true + syncSettings.InstallationID = uuid.New().String() + syncSettings.UseMailservers = true - settings.PreviewPrivacy = true - settings.Currency = "usd" - settings.ProfilePicturesVisibility = 1 - settings.LinkPreviewRequestEnabled = true + syncSettings.PreviewPrivacy = true + syncSettings.Currency = "usd" + syncSettings.ProfilePicturesVisibility = 1 + syncSettings.LinkPreviewRequestEnabled = true visibleTokens := make(map[string][]string) visibleTokens["mainnet"] = []string{"SNT"} @@ -361,14 +361,14 @@ func defaultSettings(generatedAccountInfo generator.GeneratedAccountInfo, derive return nil, err } visibleTokenJSONRaw := json.RawMessage(visibleTokensJSON) - settings.WalletVisibleTokens = &visibleTokenJSONRaw + syncSettings.WalletVisibleTokens = &visibleTokenJSONRaw networks := `[{"id":"goerli_rpc","chain-explorer-link":"https://goerli.etherscan.io/address/","name":"Goerli with upstream RPC","config":{"NetworkId":5,"DataDir":"/ethereum/goerli_rpc","UpstreamConfig":{"Enabled":true,"URL":"https://goerli-archival.gateway.pokt.network/v1/lb/3ef2018191814b7e1009b8d9"}}},{"id":"mainnet_rpc","chain-explorer-link":"https://etherscan.io/address/","name":"Mainnet with upstream RPC","config":{"NetworkId":1,"DataDir":"/ethereum/mainnet_rpc","UpstreamConfig":{"Enabled":true,"URL":"https://eth-archival.gateway.pokt.network/v1/lb/3ef2018191814b7e1009b8d9"}}}]` var networksRawMessage json.RawMessage = []byte(networks) - settings.Networks = &networksRawMessage - settings.CurrentNetwork = currentNetwork + syncSettings.Networks = &networksRawMessage + syncSettings.CurrentNetwork = currentNetwork - return settings, nil + return syncSettings, nil } func defaultNodeConfig(installationID, keyUID string) (*params.NodeConfig, error) {