Updated message handling from public and private chat

This commit is contained in:
Samuel Hawksby-Robinson 2020-11-18 12:41:36 +00:00 committed by Andrea Maria Piana
parent 8be391fc79
commit 7b230d5c9d
4 changed files with 103 additions and 17 deletions

View File

@ -3,7 +3,6 @@ package images
import (
"context"
"database/sql"
"encoding/base64"
"encoding/json"
"errors"
)
@ -114,14 +113,7 @@ func (i IdentityImage) GetType() (ImageType, error) {
}
func (i IdentityImage) GetDataURI() (string, error) {
mt, err := GetMimeType(i.Payload)
if err != nil {
return "", err
}
b64 := base64.StdEncoding.EncodeToString(i.Payload)
return "data:image/" + mt + ";base64," + b64, nil
return GetPayloadDataURI(i.Payload)
}
func (i IdentityImage) MarshalJSON() ([]byte, error) {

View File

@ -2,6 +2,7 @@ package images
import (
"bytes"
"encoding/base64"
"fmt"
"image"
"image/jpeg"
@ -55,3 +56,14 @@ func EncodeToBestSize(bb *bytes.Buffer, img image.Image, size ResizeDimension) e
return nil
}
func GetPayloadDataURI(payload []byte) (string, error) {
mt, err := GetMimeType(payload)
if err != nil {
return "", err
}
b64 := base64.StdEncoding.EncodeToString(payload)
return "data:image/" + mt + ";base64," + b64, nil
}

View File

@ -4,8 +4,8 @@ import (
"crypto/ecdsa"
"encoding/hex"
"fmt"
"github.com/pkg/errors"
"github.com/status-im/status-go/images"
"go.uber.org/zap"
"github.com/status-im/status-go/eth-node/crypto"
@ -799,3 +799,64 @@ func (m *MessageHandler) HandleGroupChatInvitation(state *ReceivedMessageState,
return nil
}
// HandleChatIdentity handles an incoming protobuf.ChatIdentity
// extracts contact information stored in the protobuf and adds it to the user's contact for update.
func (m *MessageHandler) HandleChatIdentity(state *ReceivedMessageState, ci protobuf.ChatIdentity) error {
logger := m.logger.With(zap.String("site", "HandleChatIdentity"))
contact := state.CurrentMessageState.Contact
chat, ok := state.AllChats[contact.ID]
if !ok {
chat = OneToOneFromPublicKey(state.CurrentMessageState.PublicKey, state.Timesource)
// We don't want to show the chat to the user
chat.Active = false
}
logger.Info("Handling contact update")
// TODO investigate potential race condition where user updates this contact's details and the contact update's
// clock value is just less than the ChatIdentity clock and the ChatIdentity is processed first.
// In this case the contact update would not be processed
//
// TODO Potential fix: create an ChatIdentity last updated field on the contact table.
if contact.LastUpdated < ci.Clock {
logger.Info("Updating contact")
if !contact.HasBeenAdded() && contact.ID != contactIDFromPublicKey(&m.identity.PublicKey) {
contact.SystemTags = append(contact.SystemTags, contactRequestReceived)
}
// TODO handle ENS things
/* if contact.Name != message.EnsName {
contact.Name = message.EnsName
contact.ENSVerified = false
} */
// Get the largest
var name string
var iiSize int
for n, ii := range ci.Images {
if iiSize < len(ii.Payload) {
iiSize = len(ii.Payload)
name = n
}
}
dataUri, err := images.GetPayloadDataURI(ci.Images[name].Payload)
if err != nil {
return err
}
contact.Photo = dataUri
contact.LastUpdated = ci.Clock
state.ModifiedContacts[contact.ID] = true
state.AllContacts[contact.ID] = contact
}
if chat.LastClockValue < ci.Clock {
chat.LastClockValue = ci.Clock
}
state.ModifiedChats[chat.ID] = true
state.AllChats[chat.ID] = chat
return nil
}

View File

@ -456,17 +456,18 @@ func (m *Messenger) handleSendContactCode() error {
m.logger.Error("could not build contact code advertisement", zap.Error(err))
}
if contactCodeAdvertisement == nil {
contactCodeAdvertisement = &protobuf.ContactCodeAdvertisement{}
}
err = m.handleContactCodeChatIdentity(contactCodeAdvertisement)
if err != nil {
return err
}
if contactCodeAdvertisement != nil {
payload, err = proto.Marshal(contactCodeAdvertisement)
if err != nil {
return err
}
}
contactCodeTopic := transport.ContactCodeTopic(&m.identity.PublicKey)
rawMessage := common.RawMessage{
@ -562,7 +563,7 @@ func (m *Messenger) shouldPublishChatIdentity(chatId string) (bool, error) {
// createChatIdentity creates a context based protobuf.ChatIdentity.
// context 'public-chat' will attach only the 'thumbnail' IdentityImage
// contect 'private-chat' will attach all IdentityImage
// context 'private-chat' will attach all IdentityImage
func (m *Messenger) createChatIdentity(context string) (*protobuf.ChatIdentity, error) {
ci := &protobuf.ChatIdentity{
Clock: m.transport.GetCurrentTime(),
@ -2665,13 +2666,26 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
continue
case protobuf.ContactCodeAdvertisement:
logger.Debug("Received ContactCodeAdvertisement")
cca := msg.ParsedMessage.Interface().(protobuf.ContactCodeAdvertisement)
if cca.ChatIdentity != nil {
logger.Debug("Received ContactCodeAdvertisement ChatIdentity")
err = m.handler.HandleChatIdentity(messageState, *cca.ChatIdentity)
if err != nil {
logger.Warn("failed to handle ContactCodeAdvertisement ChatIdentity", zap.Error(err))
// No continue as Chat Identity may fail but the rest of the cca may process fine.
}
}
if m.pushNotificationClient == nil {
continue
}
logger.Debug("Handling ContactCodeAdvertisement")
if err := m.pushNotificationClient.HandleContactCodeAdvertisement(publicKey, msg.ParsedMessage.Interface().(protobuf.ContactCodeAdvertisement)); err != nil {
if err := m.pushNotificationClient.HandleContactCodeAdvertisement(publicKey, cca); err != nil {
logger.Warn("failed to handle ContactCodeAdvertisement", zap.Error(err))
}
// We continue in any case, no changes to messenger
continue
@ -2724,6 +2738,13 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
logger.Warn("failed to handle GroupChatInvitation", zap.Error(err))
continue
}
case protobuf.ChatIdentity:
logger.Debug("Received ChatIdentity")
err = m.handler.HandleChatIdentity(messageState, msg.ParsedMessage.Interface().(protobuf.ChatIdentity))
if err != nil {
logger.Warn("failed to handle ChatIdentity", zap.Error(err))
continue
}
default:
// Check if is an encrypted PushNotificationRegistration