github.com/status-im/status-go@v1.1.0/protocol/messenger_sync_raw_messages.go (about)

     1  package protocol
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"github.com/golang/protobuf/proto"
     8  	"go.uber.org/zap"
     9  
    10  	"github.com/status-im/status-go/protocol/common"
    11  	"github.com/status-im/status-go/protocol/encryption/multidevice"
    12  	"github.com/status-im/status-go/protocol/protobuf"
    13  )
    14  
    15  type RawMessageHandler func(ctx context.Context, rawMessage common.RawMessage) (common.RawMessage, error)
    16  
    17  func (m *Messenger) HandleSyncRawMessages(rawMessages []*protobuf.RawMessage) error {
    18  	state := m.buildMessageState()
    19  	for _, rawMessage := range rawMessages {
    20  		switch rawMessage.GetMessageType() {
    21  		case protobuf.ApplicationMetadataMessage_CONTACT_UPDATE:
    22  			var message protobuf.ContactUpdate
    23  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
    24  			if err != nil {
    25  				return err
    26  			}
    27  			publicKey, err := common.HexToPubkey(message.PublicKey)
    28  			if err != nil {
    29  				return err
    30  			}
    31  			var contact *Contact
    32  			if c, ok := state.AllContacts.Load(message.PublicKey); ok {
    33  				contact = c
    34  			} else {
    35  				c, err := buildContact(message.PublicKey, publicKey)
    36  				if err != nil {
    37  					m.logger.Info("failed to build contact", zap.Error(err))
    38  					continue
    39  				}
    40  				contact = c
    41  				state.AllContacts.Store(message.PublicKey, contact)
    42  			}
    43  			currentMessageState := &CurrentMessageState{
    44  				Message: &protobuf.ChatMessage{
    45  					Clock: message.Clock,
    46  				},
    47  				MessageID:        " ", // make it not empty to bypass this validation: https://github.com/status-im/status-go/blob/7cd7430d3141b08f7c455d7918f4160ea8fd0559/protocol/messenger_handler.go#L325
    48  				WhisperTimestamp: message.Clock,
    49  				PublicKey:        publicKey,
    50  				Contact:          contact,
    51  			}
    52  			state.CurrentMessageState = currentMessageState
    53  			err = m.HandleContactUpdate(state, &message, nil)
    54  			if err != nil {
    55  				m.logger.Warn("failed to HandleContactUpdate when HandleSyncRawMessages", zap.Error(err))
    56  				continue
    57  			}
    58  		case protobuf.ApplicationMetadataMessage_SYNC_CHAT:
    59  			var message protobuf.SyncChat
    60  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
    61  			if err != nil {
    62  				return err
    63  			}
    64  			err = m.HandleSyncChat(state, &message, nil)
    65  			if err != nil {
    66  				m.logger.Error("error createChat when HandleSyncRawMessages", zap.Error(err))
    67  				continue
    68  			}
    69  		case protobuf.ApplicationMetadataMessage_SYNC_CHAT_REMOVED:
    70  			var message protobuf.SyncChatRemoved
    71  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
    72  			if err != nil {
    73  				return err
    74  			}
    75  			err = m.HandleSyncChatRemoved(state, &message, nil)
    76  			if err != nil {
    77  				m.logger.Error("failed to HandleSyncChatRemoved when HandleSyncRawMessages", zap.Error(err))
    78  				continue
    79  			}
    80  		case protobuf.ApplicationMetadataMessage_SYNC_CHAT_MESSAGES_READ:
    81  			var message protobuf.SyncChatMessagesRead
    82  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
    83  			if err != nil {
    84  				return err
    85  			}
    86  			err = m.HandleSyncChatMessagesRead(state, &message, nil)
    87  			if err != nil {
    88  				m.logger.Error("failed to HandleSyncChatMessagesRead when HandleSyncRawMessages", zap.Error(err))
    89  				continue
    90  			}
    91  		case protobuf.ApplicationMetadataMessage_SYNC_CLEAR_HISTORY:
    92  			var message protobuf.SyncClearHistory
    93  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
    94  			if err != nil {
    95  				return err
    96  			}
    97  			err = m.HandleSyncClearHistory(state, &message, nil)
    98  			if err != nil {
    99  				m.logger.Error("failed to handleSyncClearHistory when HandleSyncRawMessages", zap.Error(err))
   100  				continue
   101  			}
   102  		case protobuf.ApplicationMetadataMessage_SYNC_INSTALLATION_CONTACT_V2:
   103  			var message protobuf.SyncInstallationContactV2
   104  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   105  			if err != nil {
   106  				return err
   107  			}
   108  			err = m.HandleSyncInstallationContactV2(state, &message, nil)
   109  			if err != nil {
   110  				m.logger.Error("failed to HandleSyncInstallationContact when HandleSyncRawMessages", zap.Error(err))
   111  				continue
   112  			}
   113  		case protobuf.ApplicationMetadataMessage_SYNC_INSTALLATION_COMMUNITY:
   114  			var message protobuf.SyncInstallationCommunity
   115  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   116  			if err != nil {
   117  				return err
   118  			}
   119  			err = m.handleSyncInstallationCommunity(state, &message)
   120  			if err != nil {
   121  				m.logger.Error("failed to handleSyncCommunity when HandleSyncRawMessages", zap.Error(err))
   122  				continue
   123  			}
   124  		case protobuf.ApplicationMetadataMessage_SYNC_BOOKMARK:
   125  			var message protobuf.SyncBookmark
   126  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   127  			if err != nil {
   128  				return err
   129  			}
   130  			err = m.HandleSyncBookmark(state, &message, nil)
   131  			if err != nil {
   132  				m.logger.Error("failed to handleSyncBookmark when HandleSyncRawMessages", zap.Error(err))
   133  				continue
   134  			}
   135  		case protobuf.ApplicationMetadataMessage_SYNC_TRUSTED_USER:
   136  			var message protobuf.SyncTrustedUser
   137  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   138  			if err != nil {
   139  				return err
   140  			}
   141  			err = m.HandleSyncTrustedUser(state, &message, nil)
   142  			if err != nil {
   143  				m.logger.Error("failed to handleSyncTrustedUser when HandleSyncRawMessages", zap.Error(err))
   144  				continue
   145  			}
   146  		case protobuf.ApplicationMetadataMessage_SYNC_VERIFICATION_REQUEST:
   147  			var message protobuf.SyncVerificationRequest
   148  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   149  			if err != nil {
   150  				return err
   151  			}
   152  			err = m.HandleSyncVerificationRequest(state, &message, nil)
   153  			if err != nil {
   154  				m.logger.Error("failed to handleSyncVerificationRequest when HandleSyncRawMessages", zap.Error(err))
   155  				continue
   156  			}
   157  		case protobuf.ApplicationMetadataMessage_SYNC_SETTING:
   158  			var message protobuf.SyncSetting
   159  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   160  			if err != nil {
   161  				return err
   162  			}
   163  			err = m.HandleSyncSetting(state, &message, nil)
   164  			if err != nil {
   165  				m.logger.Error("failed to handleSyncSetting when HandleSyncRawMessages", zap.Error(err))
   166  				continue
   167  			}
   168  		case protobuf.ApplicationMetadataMessage_SYNC_PROFILE_PICTURES:
   169  			var message protobuf.SyncProfilePictures
   170  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   171  			if err != nil {
   172  				return err
   173  			}
   174  			err = m.HandleSyncProfilePictures(state, &message, nil)
   175  			if err != nil {
   176  				m.logger.Error("failed to HandleSyncProfilePictures when HandleSyncRawMessages", zap.Error(err))
   177  				continue
   178  			}
   179  		case protobuf.ApplicationMetadataMessage_SYNC_CONTACT_REQUEST_DECISION:
   180  			var message protobuf.SyncContactRequestDecision
   181  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   182  			if err != nil {
   183  				return err
   184  			}
   185  			err = m.HandleSyncContactRequestDecision(state, &message, nil)
   186  			if err != nil {
   187  				m.logger.Error("failed to HandleSyncContactRequestDecision when HandleSyncRawMessages", zap.Error(err))
   188  				continue
   189  			}
   190  		case protobuf.ApplicationMetadataMessage_SYNC_ACCOUNT:
   191  			var message protobuf.SyncAccount
   192  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   193  			if err != nil {
   194  				return err
   195  			}
   196  			err = m.HandleSyncAccount(state, &message, nil)
   197  			if err != nil {
   198  				m.logger.Error("failed to HandleSyncWatchOnlyAccount when HandleSyncRawMessages", zap.Error(err))
   199  				continue
   200  			}
   201  		case protobuf.ApplicationMetadataMessage_SYNC_KEYPAIR:
   202  			var message protobuf.SyncKeypair
   203  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   204  			if err != nil {
   205  				return err
   206  			}
   207  			err = m.handleSyncKeypairInternal(state, &message, true)
   208  			if err != nil {
   209  				m.logger.Error("failed to HandleSyncKeypair when HandleSyncRawMessages", zap.Error(err))
   210  				continue
   211  			}
   212  		case protobuf.ApplicationMetadataMessage_SYNC_ACCOUNTS_POSITIONS:
   213  			var message protobuf.SyncAccountsPositions
   214  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   215  			if err != nil {
   216  				return err
   217  			}
   218  			err = m.HandleSyncAccountsPositions(state, &message, nil)
   219  			if err != nil {
   220  				m.logger.Error("failed to HandleSyncAccountsPositions when HandleSyncRawMessages", zap.Error(err))
   221  				continue
   222  			}
   223  		case protobuf.ApplicationMetadataMessage_SYNC_TOKEN_PREFERENCES:
   224  			var message protobuf.SyncTokenPreferences
   225  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   226  			if err != nil {
   227  				return err
   228  			}
   229  			err = m.HandleSyncTokenPreferences(state, &message, nil)
   230  			if err != nil {
   231  				m.logger.Error("failed to HandleSyncTokenPreferences when HandleSyncRawMessages", zap.Error(err))
   232  				continue
   233  			}
   234  		case protobuf.ApplicationMetadataMessage_SYNC_COLLECTIBLE_PREFERENCES:
   235  			var message protobuf.SyncCollectiblePreferences
   236  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   237  			if err != nil {
   238  				return err
   239  			}
   240  			err = m.HandleSyncCollectiblePreferences(state, &message, nil)
   241  			if err != nil {
   242  				m.logger.Error("failed to HandleSyncCollectiblePreferences when HandleSyncRawMessages", zap.Error(err))
   243  				continue
   244  			}
   245  		case protobuf.ApplicationMetadataMessage_SYNC_SAVED_ADDRESS:
   246  			var message protobuf.SyncSavedAddress
   247  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   248  			if err != nil {
   249  				return err
   250  			}
   251  			err = m.HandleSyncSavedAddress(state, &message, nil)
   252  			if err != nil {
   253  				m.logger.Error("failed to handleSyncSavedAddress when HandleSyncRawMessages", zap.Error(err))
   254  				continue
   255  			}
   256  		case protobuf.ApplicationMetadataMessage_SYNC_ENS_USERNAME_DETAIL:
   257  			var message protobuf.SyncEnsUsernameDetail
   258  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   259  			if err != nil {
   260  				return err
   261  			}
   262  			err = m.HandleSyncEnsUsernameDetail(state, &message, nil)
   263  			if err != nil {
   264  				m.logger.Error("failed to handleSyncEnsUsernameDetail when HandleSyncRawMessages", zap.Error(err))
   265  				continue
   266  			}
   267  		case protobuf.ApplicationMetadataMessage_SYNC_DELETE_FOR_ME_MESSAGE:
   268  			var message protobuf.SyncDeleteForMeMessage
   269  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   270  			if err != nil {
   271  				return err
   272  			}
   273  			err = m.HandleSyncDeleteForMeMessage(state, &message, nil)
   274  			if err != nil {
   275  				m.logger.Error("failed to HandleDeleteForMeMessage when HandleSyncRawMessages", zap.Error(err))
   276  				continue
   277  			}
   278  		case protobuf.ApplicationMetadataMessage_SYNC_PAIR_INSTALLATION:
   279  			var message protobuf.SyncPairInstallation
   280  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   281  			if err != nil {
   282  				return err
   283  			}
   284  			identity := m.myHexIdentity()
   285  			installations := []*multidevice.Installation{
   286  				{
   287  					Identity:  identity,
   288  					ID:        message.InstallationId,
   289  					Version:   message.Version,
   290  					Enabled:   true,
   291  					Timestamp: int64(message.Clock),
   292  					InstallationMetadata: &multidevice.InstallationMetadata{
   293  						DeviceType: message.DeviceType,
   294  						Name:       message.Name,
   295  					},
   296  				}}
   297  			m.handleInstallations(installations)
   298  			// set WhisperTimestamp to pass the validation in HandleSyncPairInstallation
   299  			state.CurrentMessageState = &CurrentMessageState{WhisperTimestamp: message.Clock}
   300  			err = m.HandleSyncPairInstallation(state, &message, nil)
   301  			if err != nil {
   302  				return err
   303  			}
   304  
   305  			multidevice := m.encryptor.GetMultiDevice()
   306  			if multidevice == nil {
   307  				return errors.New("multidevice is nil")
   308  			}
   309  			_, err = multidevice.AddInstallations(m.IdentityPublicKeyCompressed(), int64(message.GetClock()), installations, true)
   310  			if err != nil {
   311  				return err
   312  			}
   313  			// if receiver already logged in before local pairing, we need force enable the installation,
   314  			// AddInstallations won't make sure enable it, e.g. installation maybe already exist in db but not enabled yet
   315  			err = m.EnableInstallation(message.InstallationId)
   316  			if err != nil {
   317  				return err
   318  			}
   319  		case protobuf.ApplicationMetadataMessage_SYNC_PROFILE_SHOWCASE_PREFERENCES:
   320  			var message protobuf.SyncProfileShowcasePreferences
   321  			err := proto.Unmarshal(rawMessage.GetPayload(), &message)
   322  			if err != nil {
   323  				return err
   324  			}
   325  			_, err = m.saveProfileShowcasePreferencesProto(&message, false)
   326  			if err != nil {
   327  				return err
   328  			}
   329  		}
   330  	}
   331  	response, err := m.saveDataAndPrepareResponse(state)
   332  	if err != nil {
   333  		return err
   334  	}
   335  	m.PublishMessengerResponse(response)
   336  	return nil
   337  }