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 }