2023-03-23 11:44:15 +00:00
|
|
|
package pairing
|
|
|
|
|
|
|
|
import (
|
2023-04-02 23:08:29 +00:00
|
|
|
"encoding/json"
|
2023-03-23 11:44:15 +00:00
|
|
|
"errors"
|
|
|
|
|
|
|
|
"github.com/golang/protobuf/proto"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
|
|
|
"github.com/status-im/status-go/api"
|
|
|
|
"github.com/status-im/status-go/multiaccounts"
|
2023-04-02 23:08:29 +00:00
|
|
|
"github.com/status-im/status-go/multiaccounts/accounts"
|
|
|
|
"github.com/status-im/status-go/multiaccounts/settings"
|
2023-03-23 11:44:15 +00:00
|
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
|
|
|
)
|
|
|
|
|
|
|
|
const keystoreDir = "keystore"
|
|
|
|
|
|
|
|
var (
|
|
|
|
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")
|
|
|
|
ErrLoggedInKeyUIDConflict = errors.New("logged in keyUID not same as keyUID in payload")
|
|
|
|
)
|
|
|
|
|
|
|
|
// AccountPayload represents the payload structure a Server handles
|
|
|
|
type AccountPayload struct {
|
2023-09-12 19:31:46 +00:00
|
|
|
keys map[string][]byte // nolint: structcheck
|
|
|
|
multiaccount *multiaccounts.Account
|
|
|
|
password string
|
|
|
|
chatKey string
|
2023-03-23 11:44:15 +00:00
|
|
|
//flag if account already exist before sync account
|
|
|
|
exist bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// AccountPayloadMarshaller is responsible for marshalling and unmarshalling Server payload data
|
|
|
|
type AccountPayloadMarshaller struct {
|
|
|
|
logger *zap.Logger
|
|
|
|
*AccountPayload
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPairingPayloadMarshaller(ap *AccountPayload, logger *zap.Logger) *AccountPayloadMarshaller {
|
|
|
|
return &AccountPayloadMarshaller{logger: logger, AccountPayload: ap}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ppm *AccountPayloadMarshaller) MarshalProtobuf() ([]byte, error) {
|
2023-08-18 08:51:16 +00:00
|
|
|
lpp := &protobuf.LocalPairingPayload{
|
2023-09-12 19:31:46 +00:00
|
|
|
Keys: ppm.accountKeysToProtobuf(),
|
|
|
|
Password: ppm.password,
|
|
|
|
ChatKey: ppm.chatKey,
|
2023-08-18 08:51:16 +00:00
|
|
|
}
|
|
|
|
if ppm.multiaccount != nil {
|
|
|
|
lpp.Multiaccount = ppm.multiaccount.ToProtobuf()
|
|
|
|
}
|
|
|
|
return proto.Marshal(lpp)
|
2023-03-23 11:44:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ppm *AccountPayloadMarshaller) accountKeysToProtobuf() []*protobuf.LocalPairingPayload_Key {
|
|
|
|
var keys []*protobuf.LocalPairingPayload_Key
|
|
|
|
for name, data := range ppm.keys {
|
|
|
|
keys = append(keys, &protobuf.LocalPairingPayload_Key{Name: name, Data: data})
|
|
|
|
}
|
|
|
|
return keys
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ppm *AccountPayloadMarshaller) UnmarshalProtobuf(data []byte) error {
|
|
|
|
l := ppm.logger.Named("UnmarshalProtobuf()")
|
|
|
|
l.Debug("fired")
|
|
|
|
|
|
|
|
pb := new(protobuf.LocalPairingPayload)
|
|
|
|
err := proto.Unmarshal(data, pb)
|
|
|
|
l.Debug(
|
|
|
|
"after protobuf.LocalPairingPayload",
|
|
|
|
zap.Any("pb", pb),
|
|
|
|
zap.Any("pb.Multiaccount", pb.Multiaccount),
|
|
|
|
zap.Any("pb.Keys", pb.Keys),
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
ppm.accountKeysFromProtobuf(pb.Keys)
|
2023-08-18 08:51:16 +00:00
|
|
|
if pb.Multiaccount != nil {
|
|
|
|
ppm.multiaccountFromProtobuf(pb.Multiaccount)
|
|
|
|
}
|
2023-03-23 11:44:15 +00:00
|
|
|
ppm.password = pb.Password
|
2023-06-09 06:43:51 +00:00
|
|
|
ppm.chatKey = pb.ChatKey
|
2023-09-12 19:31:46 +00:00
|
|
|
|
2023-03-23 11:44:15 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ppm *AccountPayloadMarshaller) accountKeysFromProtobuf(pbKeys []*protobuf.LocalPairingPayload_Key) {
|
|
|
|
l := ppm.logger.Named("accountKeysFromProtobuf()")
|
|
|
|
l.Debug("fired")
|
|
|
|
|
|
|
|
if ppm.keys == nil {
|
|
|
|
ppm.keys = make(map[string][]byte)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, key := range pbKeys {
|
|
|
|
ppm.keys[key.Name] = key.Data
|
|
|
|
}
|
|
|
|
l.Debug(
|
|
|
|
"after for _, key := range pbKeys",
|
|
|
|
zap.Any("pbKeys", pbKeys),
|
|
|
|
zap.Any("accountPayloadMarshaller.keys", ppm.keys),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ppm *AccountPayloadMarshaller) multiaccountFromProtobuf(pbMultiAccount *protobuf.MultiAccount) {
|
|
|
|
ppm.multiaccount = new(multiaccounts.Account)
|
|
|
|
ppm.multiaccount.FromProtobuf(pbMultiAccount)
|
|
|
|
}
|
|
|
|
|
2023-04-02 23:08:29 +00:00
|
|
|
type RawMessagesPayload struct {
|
2023-05-16 10:48:00 +00:00
|
|
|
rawMessages []*protobuf.RawMessage
|
|
|
|
profileKeypair *accounts.Keypair
|
|
|
|
setting *settings.Settings
|
2023-04-02 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewRawMessagesPayload() *RawMessagesPayload {
|
|
|
|
return &RawMessagesPayload{
|
|
|
|
setting: new(settings.Settings),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-29 17:12:27 +00:00
|
|
|
// RawMessagePayloadMarshaller is responsible for marshalling and unmarshalling raw message data
|
|
|
|
type RawMessagePayloadMarshaller struct {
|
2023-04-02 23:08:29 +00:00
|
|
|
payload *RawMessagesPayload
|
2023-03-29 17:12:27 +00:00
|
|
|
}
|
|
|
|
|
2023-04-02 23:08:29 +00:00
|
|
|
func NewRawMessagePayloadMarshaller(payload *RawMessagesPayload) *RawMessagePayloadMarshaller {
|
2023-03-29 17:12:27 +00:00
|
|
|
return &RawMessagePayloadMarshaller{
|
|
|
|
payload: payload,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-02 23:08:29 +00:00
|
|
|
func (rmm *RawMessagePayloadMarshaller) MarshalProtobuf() (data []byte, err error) {
|
|
|
|
syncRawMessage := new(protobuf.SyncRawMessage)
|
|
|
|
|
|
|
|
syncRawMessage.RawMessages = rmm.payload.rawMessages
|
2023-05-16 10:48:00 +00:00
|
|
|
if rmm.payload.profileKeypair != nil && len(rmm.payload.profileKeypair.KeyUID) > 0 {
|
|
|
|
syncRawMessage.SubAccountsJsonBytes, err = json.Marshal(rmm.payload.profileKeypair)
|
2023-04-02 23:08:29 +00:00
|
|
|
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 {
|
2023-05-16 10:48:00 +00:00
|
|
|
err = json.Unmarshal(syncRawMessage.SubAccountsJsonBytes, &rmm.payload.profileKeypair)
|
2023-04-02 23:08:29 +00:00
|
|
|
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
|
2023-03-29 17:12:27 +00:00
|
|
|
}
|
|
|
|
|
2023-03-23 11:44:15 +00:00
|
|
|
// InstallationPayloadMounterReceiver represents an InstallationPayload Repository
|
|
|
|
type InstallationPayloadMounterReceiver struct {
|
2023-03-30 10:00:32 +00:00
|
|
|
PayloadMounter
|
2023-04-02 23:08:29 +00:00
|
|
|
PayloadReceiver
|
2023-03-23 11:44:15 +00:00
|
|
|
}
|
|
|
|
|
2023-04-02 23:08:29 +00:00
|
|
|
func NewInstallationPayloadMounterReceiver(encryptor *PayloadEncryptor, backend *api.GethStatusBackend, deviceType string) *InstallationPayloadMounterReceiver {
|
2023-03-23 11:44:15 +00:00
|
|
|
return &InstallationPayloadMounterReceiver{
|
2023-04-02 23:08:29 +00:00
|
|
|
NewInstallationPayloadMounter(encryptor, backend, deviceType),
|
|
|
|
NewInstallationPayloadReceiver(encryptor, backend, deviceType),
|
2023-03-23 11:44:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *InstallationPayloadMounterReceiver) LockPayload() {
|
2023-03-30 10:00:32 +00:00
|
|
|
i.PayloadMounter.LockPayload()
|
2023-04-02 23:08:29 +00:00
|
|
|
i.PayloadReceiver.LockPayload()
|
2023-03-23 11:44:15 +00:00
|
|
|
}
|