mirror of
https://github.com/status-im/status-go.git
synced 2025-02-16 16:56:53 +00:00
Use local chat-id for matching messages
This commit is contained in:
parent
d067b56fc2
commit
29f25c5486
@ -129,7 +129,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesWrapped() {
|
|||||||
s.Require().Equal(1, len(decodedMessages))
|
s.Require().Equal(1, len(decodedMessages))
|
||||||
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
|
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
|
||||||
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
|
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
|
||||||
parsedMessage := decodedMessages[0].ParsedMessage.(protobuf.ChatMessage)
|
parsedMessage := decodedMessages[0].ParsedMessage.Interface().(protobuf.ChatMessage)
|
||||||
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
|
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
|
||||||
s.Require().True(proto.Equal(&s.testMessage, &parsedMessage))
|
s.Require().True(proto.Equal(&s.testMessage, &parsedMessage))
|
||||||
s.Require().Equal(protobuf.ApplicationMetadataMessage_CHAT_MESSAGE, decodedMessages[0].Type)
|
s.Require().Equal(protobuf.ApplicationMetadataMessage_CHAT_MESSAGE, decodedMessages[0].Type)
|
||||||
@ -167,7 +167,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasync() {
|
|||||||
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
|
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
|
||||||
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
|
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
|
||||||
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
|
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
|
||||||
parsedMessage := decodedMessages[0].ParsedMessage.(protobuf.ChatMessage)
|
parsedMessage := decodedMessages[0].ParsedMessage.Interface().(protobuf.ChatMessage)
|
||||||
s.Require().True(proto.Equal(&s.testMessage, &parsedMessage))
|
s.Require().True(proto.Equal(&s.testMessage, &parsedMessage))
|
||||||
s.Require().Equal(protobuf.ApplicationMetadataMessage_CHAT_MESSAGE, decodedMessages[0].Type)
|
s.Require().Equal(protobuf.ApplicationMetadataMessage_CHAT_MESSAGE, decodedMessages[0].Type)
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasyncEncrypted() {
|
|||||||
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
|
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
|
||||||
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
|
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
|
||||||
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
|
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
|
||||||
parsedMessage := decodedMessages[0].ParsedMessage.(protobuf.ChatMessage)
|
parsedMessage := decodedMessages[0].ParsedMessage.Interface().(protobuf.ChatMessage)
|
||||||
s.Require().True(proto.Equal(&s.testMessage, &parsedMessage))
|
s.Require().True(proto.Equal(&s.testMessage, &parsedMessage))
|
||||||
s.Require().Equal(protobuf.ApplicationMetadataMessage_CHAT_MESSAGE, decodedMessages[0].Type)
|
s.Require().Equal(protobuf.ApplicationMetadataMessage_CHAT_MESSAGE, decodedMessages[0].Type)
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,14 @@ type EmojiReaction struct {
|
|||||||
|
|
||||||
// SigPubKey is the ecdsa encoded public key of the emoji reaction author
|
// SigPubKey is the ecdsa encoded public key of the emoji reaction author
|
||||||
SigPubKey *ecdsa.PublicKey `json:"-"`
|
SigPubKey *ecdsa.PublicKey `json:"-"`
|
||||||
|
|
||||||
|
// LocalChatID is the chatID of the local chat (one-to-one are not symmetric)
|
||||||
|
LocalChatID string `json:"localChatId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID is the Keccak256() contatenation of From-ChatID-MessageID-EmojiType
|
// ID is the Keccak256() contatenation of From-MessageID-EmojiType
|
||||||
func (e EmojiReaction) ID() string {
|
func (e EmojiReaction) ID() string {
|
||||||
return types.EncodeHex(crypto.Keccak256([]byte(fmt.Sprintf("%s%s%s%d", e.From, e.ChatId, e.MessageId, e.Type))))
|
return types.EncodeHex(crypto.Keccak256([]byte(fmt.Sprintf("%s%s%d", e.From, e.MessageId, e.Type))))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSigPubKey returns an ecdsa encoded public key
|
// GetSigPubKey returns an ecdsa encoded public key
|
||||||
|
@ -670,10 +670,20 @@ func (m *MessageHandler) messageExists(messageID string, existingMessagesMap map
|
|||||||
|
|
||||||
func (m *MessageHandler) HandleEmojiReaction(state *ReceivedMessageState, pbEmojiR protobuf.EmojiReaction) error {
|
func (m *MessageHandler) HandleEmojiReaction(state *ReceivedMessageState, pbEmojiR protobuf.EmojiReaction) error {
|
||||||
logger := m.logger.With(zap.String("site", "HandleEmojiReaction"))
|
logger := m.logger.With(zap.String("site", "HandleEmojiReaction"))
|
||||||
|
if err := ValidateReceivedEmojiReaction(&pbEmojiR, state.Timesource.GetCurrentTime()); err != nil {
|
||||||
|
logger.Error("invalid emoji reaction", zap.Error(err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
from := state.CurrentMessageState.Contact.ID
|
from := state.CurrentMessageState.Contact.ID
|
||||||
|
|
||||||
// check that the user can actually send an emoji for this message
|
emojiReaction := &EmojiReaction{
|
||||||
existingEmoji, err := m.persistence.EmojiReactionByFromMessageIDAndType(from, pbEmojiR.MessageId, pbEmojiR.Type)
|
EmojiReaction: pbEmojiR,
|
||||||
|
From: from,
|
||||||
|
SigPubKey: state.CurrentMessageState.PublicKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
existingEmoji, err := m.persistence.EmojiReactionByID(emojiReaction.ID())
|
||||||
if err != errRecordNotFound && err != nil {
|
if err != errRecordNotFound && err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -683,18 +693,15 @@ func (m *MessageHandler) HandleEmojiReaction(state *ReceivedMessageState, pbEmoj
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
emojiReaction := &EmojiReaction{
|
|
||||||
EmojiReaction: pbEmojiR,
|
|
||||||
From: from,
|
|
||||||
SigPubKey: state.CurrentMessageState.PublicKey,
|
|
||||||
}
|
|
||||||
chat, err := m.matchChatEntity(emojiReaction, state.AllChats, state.Timesource)
|
chat, err := m.matchChatEntity(emojiReaction, state.AllChats, state.Timesource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err // matchChatEntity returns a descriptive error message
|
return err // matchChatEntity returns a descriptive error message
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make sure the user can actualy send an emoji for this chat.
|
// Set local chat id
|
||||||
logger.Info("Handling emoji reaction")
|
emojiReaction.LocalChatID = chat.ID
|
||||||
|
|
||||||
|
logger.Debug("Handling emoji reaction")
|
||||||
|
|
||||||
if chat.LastClockValue < pbEmojiR.Clock {
|
if chat.LastClockValue < pbEmojiR.Clock {
|
||||||
chat.LastClockValue = pbEmojiR.Clock
|
chat.LastClockValue = pbEmojiR.Clock
|
||||||
|
@ -408,6 +408,7 @@ func (db sqlitePersistence) MessagesByIDs(ids []string) ([]*Message, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
var result []*Message
|
var result []*Message
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var message Message
|
var message Message
|
||||||
@ -496,14 +497,14 @@ func (db sqlitePersistence) EmojiReactionsByChatID(chatID string, currCursor str
|
|||||||
if currCursor != "" {
|
if currCursor != "" {
|
||||||
cursorWhere = "AND substr('0000000000000000000000000000000000000000000000000000000000000000' || m.clock_value, -64, 64) || m.id <= ?"
|
cursorWhere = "AND substr('0000000000000000000000000000000000000000000000000000000000000000' || m.clock_value, -64, 64) || m.id <= ?"
|
||||||
}
|
}
|
||||||
args := []interface{}{chatID}
|
args := []interface{}{chatID, chatID}
|
||||||
if currCursor != "" {
|
if currCursor != "" {
|
||||||
args = append(args, currCursor)
|
args = append(args, currCursor)
|
||||||
}
|
}
|
||||||
args = append(args, limit)
|
args = append(args, limit)
|
||||||
// Build a new column `cursor` at the query time by having a fixed-sized clock value at the beginning
|
// NOTE: We match against local_chat_id for security reasons.
|
||||||
// concatenated with message ID. Results are sorted using this new column.
|
// As a user could potentially send an emoji reaction for a one to
|
||||||
// This new column values can also be returned as a cursor for subsequent requests.
|
// one/group chat that has no access to.
|
||||||
query := fmt.Sprintf(`
|
query := fmt.Sprintf(`
|
||||||
SELECT
|
SELECT
|
||||||
e.clock_value,
|
e.clock_value,
|
||||||
@ -511,11 +512,14 @@ func (db sqlitePersistence) EmojiReactionsByChatID(chatID string, currCursor str
|
|||||||
e.emoji_id,
|
e.emoji_id,
|
||||||
e.message_id,
|
e.message_id,
|
||||||
e.chat_id,
|
e.chat_id,
|
||||||
|
e.local_chat_id,
|
||||||
e.retracted
|
e.retracted
|
||||||
FROM
|
FROM
|
||||||
emoji_reactions e
|
emoji_reactions e
|
||||||
WHERE NOT(e.retracted)
|
WHERE NOT(e.retracted)
|
||||||
AND
|
AND
|
||||||
|
e.local_chat_id = ?
|
||||||
|
AND
|
||||||
e.message_id IN
|
e.message_id IN
|
||||||
(SELECT id FROM user_messages m WHERE NOT(m.hide) AND m.local_chat_id = ? %s
|
(SELECT id FROM user_messages m WHERE NOT(m.hide) AND m.local_chat_id = ? %s
|
||||||
ORDER BY substr('0000000000000000000000000000000000000000000000000000000000000000' || m.clock_value, -64, 64) || m.id DESC LIMIT ?)
|
ORDER BY substr('0000000000000000000000000000000000000000000000000000000000000000' || m.clock_value, -64, 64) || m.id DESC LIMIT ?)
|
||||||
@ -539,6 +543,7 @@ func (db sqlitePersistence) EmojiReactionsByChatID(chatID string, currCursor str
|
|||||||
&emojiReaction.Type,
|
&emojiReaction.Type,
|
||||||
&emojiReaction.MessageId,
|
&emojiReaction.MessageId,
|
||||||
&emojiReaction.ChatId,
|
&emojiReaction.ChatId,
|
||||||
|
&emojiReaction.LocalChatID,
|
||||||
&emojiReaction.Retracted)
|
&emojiReaction.Retracted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -768,7 +773,7 @@ func (db sqlitePersistence) BlockContact(contact *Contact) ([]*Chat, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db sqlitePersistence) SaveEmojiReaction(emojiReaction *EmojiReaction) (err error) {
|
func (db sqlitePersistence) SaveEmojiReaction(emojiReaction *EmojiReaction) (err error) {
|
||||||
query := "INSERT INTO emoji_reactions(id,clock_value,source,emoji_id,message_id,chat_id,retracted) VALUES (?,?,?,?,?,?,?)"
|
query := "INSERT INTO emoji_reactions(id,clock_value,source,emoji_id,message_id,chat_id,local_chat_id,retracted) VALUES (?,?,?,?,?,?,?,?)"
|
||||||
stmt, err := db.db.Prepare(query)
|
stmt, err := db.db.Prepare(query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -781,6 +786,7 @@ func (db sqlitePersistence) SaveEmojiReaction(emojiReaction *EmojiReaction) (err
|
|||||||
emojiReaction.Type,
|
emojiReaction.Type,
|
||||||
emojiReaction.MessageId,
|
emojiReaction.MessageId,
|
||||||
emojiReaction.ChatId,
|
emojiReaction.ChatId,
|
||||||
|
emojiReaction.LocalChatID,
|
||||||
emojiReaction.Retracted,
|
emojiReaction.Retracted,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -788,26 +794,14 @@ func (db sqlitePersistence) SaveEmojiReaction(emojiReaction *EmojiReaction) (err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db sqlitePersistence) EmojiReactionByID(id string) (*EmojiReaction, error) {
|
func (db sqlitePersistence) EmojiReactionByID(id string) (*EmojiReaction, error) {
|
||||||
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
row := db.db.QueryRow(
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err == nil {
|
|
||||||
err = tx.Commit()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// don't shadow original error
|
|
||||||
_ = tx.Rollback()
|
|
||||||
}()
|
|
||||||
|
|
||||||
row := tx.QueryRow(
|
|
||||||
`SELECT
|
`SELECT
|
||||||
clock_value,
|
clock_value,
|
||||||
source,
|
source,
|
||||||
emoji_id,
|
emoji_id,
|
||||||
message_id,
|
message_id,
|
||||||
chat_id,
|
chat_id,
|
||||||
|
local_chat_id,
|
||||||
retracted
|
retracted
|
||||||
FROM
|
FROM
|
||||||
emoji_reactions
|
emoji_reactions
|
||||||
@ -816,71 +810,15 @@ func (db sqlitePersistence) EmojiReactionByID(id string) (*EmojiReaction, error)
|
|||||||
`, id)
|
`, id)
|
||||||
|
|
||||||
emojiReaction := new(EmojiReaction)
|
emojiReaction := new(EmojiReaction)
|
||||||
args := []interface{}{
|
err := row.Scan(&emojiReaction.Clock,
|
||||||
&emojiReaction.Clock,
|
|
||||||
&emojiReaction.From,
|
&emojiReaction.From,
|
||||||
&emojiReaction.Type,
|
&emojiReaction.Type,
|
||||||
&emojiReaction.MessageId,
|
&emojiReaction.MessageId,
|
||||||
&emojiReaction.ChatId,
|
&emojiReaction.ChatId,
|
||||||
|
&emojiReaction.LocalChatID,
|
||||||
&emojiReaction.Retracted,
|
&emojiReaction.Retracted,
|
||||||
}
|
|
||||||
err = row.Scan(args...)
|
|
||||||
|
|
||||||
switch err {
|
|
||||||
case sql.ErrNoRows:
|
|
||||||
return nil, errRecordNotFound
|
|
||||||
case nil:
|
|
||||||
return emojiReaction, nil
|
|
||||||
default:
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db sqlitePersistence) EmojiReactionByFromMessageIDAndType(from string, messageID string, emojiType protobuf.EmojiReaction_Type) (*EmojiReaction, error) {
|
|
||||||
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err == nil {
|
|
||||||
err = tx.Commit()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// don't shadow original error
|
|
||||||
_ = tx.Rollback()
|
|
||||||
}()
|
|
||||||
|
|
||||||
row := tx.QueryRow(
|
|
||||||
`SELECT
|
|
||||||
clock_value,
|
|
||||||
source,
|
|
||||||
emoji_id,
|
|
||||||
message_id,
|
|
||||||
chat_id,
|
|
||||||
retracted
|
|
||||||
|
|
||||||
FROM
|
|
||||||
emoji_reactions
|
|
||||||
WHERE
|
|
||||||
emoji_reactions.source = ?
|
|
||||||
AND
|
|
||||||
emoji_reactions.message_id = ?
|
|
||||||
AND
|
|
||||||
emoji_reactions.emoji_id = ?
|
|
||||||
`,
|
|
||||||
from,
|
|
||||||
messageID,
|
|
||||||
emojiType,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
emojiReaction := new(EmojiReaction)
|
|
||||||
err = row.Scan(&emojiReaction.Clock,
|
|
||||||
&emojiReaction.From,
|
|
||||||
&emojiReaction.Type,
|
|
||||||
&emojiReaction.MessageId,
|
|
||||||
&emojiReaction.ChatId,
|
|
||||||
&emojiReaction.Retracted)
|
|
||||||
|
|
||||||
switch err {
|
switch err {
|
||||||
case sql.ErrNoRows:
|
case sql.ErrNoRows:
|
||||||
return nil, errRecordNotFound
|
return nil, errRecordNotFound
|
||||||
@ -890,8 +828,3 @@ func (db sqlitePersistence) EmojiReactionByFromMessageIDAndType(from string, mes
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db sqlitePersistence) RetractEmojiReaction(id string) error {
|
|
||||||
_, err := db.db.Exec(`UPDATE emoji_reactions SET retracted = 1 WHERE id = ?`, id)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
@ -225,3 +225,27 @@ func ValidateReceivedChatMessage(message *protobuf.ChatMessage, whisperTimestamp
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ValidateReceivedEmojiReaction(emoji *protobuf.EmojiReaction, whisperTimestamp uint64) error {
|
||||||
|
if err := validateClockValue(emoji.Clock, whisperTimestamp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(emoji.MessageId) == 0 {
|
||||||
|
return errors.New("message-id can't be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(emoji.ChatId) == 0 {
|
||||||
|
return errors.New("chat-id can't be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if emoji.Type == protobuf.EmojiReaction_UNKNOWN_EMOJI_REACTION_TYPE {
|
||||||
|
return errors.New("unknown emoji reaction type")
|
||||||
|
}
|
||||||
|
|
||||||
|
if emoji.MessageType == protobuf.MessageType_UNKNOWN_MESSAGE_TYPE {
|
||||||
|
return errors.New("unknown message type")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -477,3 +477,105 @@ func (s *MessageValidatorSuite) TestValidatePlainTextMessage() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *MessageValidatorSuite) TestValidateEmojiReaction() {
|
||||||
|
testCases := []struct {
|
||||||
|
Name string
|
||||||
|
Valid bool
|
||||||
|
WhisperTimestamp uint64
|
||||||
|
Message protobuf.EmojiReaction
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "valid emoji reaction",
|
||||||
|
Valid: true,
|
||||||
|
WhisperTimestamp: 30,
|
||||||
|
Message: protobuf.EmojiReaction{
|
||||||
|
Clock: 30,
|
||||||
|
ChatId: "chat-id",
|
||||||
|
MessageId: "message-id",
|
||||||
|
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||||
|
Type: protobuf.EmojiReaction_LOVE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "valid emoji retraction",
|
||||||
|
Valid: true,
|
||||||
|
WhisperTimestamp: 30,
|
||||||
|
Message: protobuf.EmojiReaction{
|
||||||
|
Clock: 30,
|
||||||
|
ChatId: "0.34",
|
||||||
|
MessageId: "message-id",
|
||||||
|
Type: protobuf.EmojiReaction_LOVE,
|
||||||
|
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||||
|
Retracted: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "missing chatID",
|
||||||
|
Valid: false,
|
||||||
|
WhisperTimestamp: 30,
|
||||||
|
Message: protobuf.EmojiReaction{
|
||||||
|
Clock: 30,
|
||||||
|
MessageId: "message-id",
|
||||||
|
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||||
|
Type: protobuf.EmojiReaction_LOVE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "missing messageID",
|
||||||
|
Valid: false,
|
||||||
|
WhisperTimestamp: 30,
|
||||||
|
Message: protobuf.EmojiReaction{
|
||||||
|
Clock: 30,
|
||||||
|
ChatId: "chat-id",
|
||||||
|
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||||
|
Type: protobuf.EmojiReaction_LOVE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "missing type",
|
||||||
|
Valid: false,
|
||||||
|
WhisperTimestamp: 30,
|
||||||
|
Message: protobuf.EmojiReaction{
|
||||||
|
Clock: 30,
|
||||||
|
ChatId: "chat-id",
|
||||||
|
MessageId: "message-id",
|
||||||
|
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "missing message type",
|
||||||
|
Valid: false,
|
||||||
|
WhisperTimestamp: 30,
|
||||||
|
Message: protobuf.EmojiReaction{
|
||||||
|
Clock: 30,
|
||||||
|
ChatId: "chat-id",
|
||||||
|
MessageId: "message-id",
|
||||||
|
Type: protobuf.EmojiReaction_LOVE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "clock value too high",
|
||||||
|
Valid: false,
|
||||||
|
WhisperTimestamp: 30,
|
||||||
|
Message: protobuf.EmojiReaction{
|
||||||
|
Clock: 900000,
|
||||||
|
ChatId: "chat-id",
|
||||||
|
MessageId: "message-id",
|
||||||
|
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||||
|
Type: protobuf.EmojiReaction_LOVE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
s.Run(tc.Name, func() {
|
||||||
|
err := ValidateReceivedEmojiReaction(&tc.Message, tc.WhisperTimestamp)
|
||||||
|
if tc.Valid {
|
||||||
|
s.Nil(err)
|
||||||
|
} else {
|
||||||
|
s.NotNil(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -3245,7 +3245,8 @@ func (m *Messenger) SendEmojiReaction(ctx context.Context, chatID, messageID str
|
|||||||
ChatId: chatID,
|
ChatId: chatID,
|
||||||
Type: protobuf.EmojiReaction_Type(emojiID),
|
Type: protobuf.EmojiReaction_Type(emojiID),
|
||||||
},
|
},
|
||||||
From: types.EncodeHex(crypto.FromECDSAPub(&m.identity.PublicKey)),
|
LocalChatID: chatID,
|
||||||
|
From: types.EncodeHex(crypto.FromECDSAPub(&m.identity.PublicKey)),
|
||||||
}
|
}
|
||||||
encodedMessage, err := m.encodeChatEntity(chat, emojiR)
|
encodedMessage, err := m.encodeChatEntity(chat, emojiR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -3334,7 +3335,7 @@ func (m *Messenger) SendEmojiReactionRetraction(ctx context.Context, emojiReacti
|
|||||||
response.Chats = []*Chat{chat}
|
response.Chats = []*Chat{chat}
|
||||||
|
|
||||||
// Persist retraction state for emoji reaction
|
// Persist retraction state for emoji reaction
|
||||||
err = m.persistence.RetractEmojiReaction(emojiReactionID)
|
err = m.persistence.SaveEmojiReaction(emojiR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
// 1595862781_add_audio_data.down.sql (0)
|
// 1595862781_add_audio_data.down.sql (0)
|
||||||
// 1595862781_add_audio_data.up.sql (246B)
|
// 1595862781_add_audio_data.up.sql (246B)
|
||||||
// 1595865249_create_emoji_reactions_table.down.sql (27B)
|
// 1595865249_create_emoji_reactions_table.down.sql (27B)
|
||||||
// 1595865249_create_emoji_reactions_table.up.sql (265B)
|
// 1595865249_create_emoji_reactions_table.up.sql (300B)
|
||||||
// doc.go (850B)
|
// doc.go (850B)
|
||||||
|
|
||||||
package migrations
|
package migrations
|
||||||
@ -427,7 +427,7 @@ func _1595865249_create_emoji_reactions_tableDownSql() (*asset, error) {
|
|||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var __1595865249_create_emoji_reactions_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xce\xbf\x4e\xc3\x30\x10\xc7\xf1\x3d\x52\xde\xe1\x37\x82\xc4\xc0\xce\x64\xcc\x45\x58\x18\xa7\x72\xaf\xa8\x9d\x22\xcb\x3d\x81\xa1\xc5\x92\xed\xf0\xfc\x88\x64\xe1\x8f\x98\x3f\x77\xdf\x3b\xed\x49\x31\x81\xd5\xad\x25\x98\x01\x6e\x64\xd0\xde\x6c\x79\x0b\x39\xe7\xd7\x34\x15\x09\xb1\xa5\xfc\x5e\x71\xd1\x77\x40\x3a\xe2\x49\x79\x7d\xaf\x3c\x36\xde\x3c\x2a\x7f\xc0\x03\x1d\x30\x3a\xe8\xd1\x0d\xd6\x68\x86\xa7\x8d\x55\x9a\xae\xbe\xc6\xe3\x29\xc7\xb7\xe9\x23\x9c\x66\x81\x71\xbc\xe4\xdd\xce\xda\x05\x6b\x9e\x4b\x14\x30\xed\x7f\xc1\x7a\x39\x1d\xff\xae\x9c\xa5\xd6\xf0\x2c\xd3\xb7\x37\x7e\x78\x7c\x09\xed\x5f\x2c\xd2\x4a\x88\x4d\xd6\xee\x1d\x0d\x6a\x67\x19\xd7\x7d\x77\x79\xd3\x77\x9f\x01\x00\x00\xff\xff\xf2\xdf\x03\x4e\x09\x01\x00\x00")
|
var __1595865249_create_emoji_reactions_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\xce\xbd\x4e\x03\x31\x10\x04\xe0\xfe\xa4\x7b\x87\x29\x41\xa2\xa0\xa7\x32\x66\x4f\x58\x18\x5f\xe4\x6c\x50\x52\x9d\x2c\x67\x05\x07\x0e\x96\x6c\x87\xe7\x47\xe4\x1a\x7e\x44\xea\x6f\x76\x67\xb4\x27\xc5\x04\x56\xb7\x96\x60\x06\xb8\x91\x41\x5b\xb3\xe6\x35\xe4\x90\x5f\xe7\xa9\x48\x88\x6d\xce\xef\x15\x17\x7d\x07\xcc\x7b\x3c\x29\xaf\xef\x95\xc7\xca\x9b\x47\xe5\x77\x78\xa0\x1d\x46\x07\x3d\xba\xc1\x1a\xcd\xf0\xb4\xb2\x4a\xd3\xd5\x57\x3c\xa6\x1c\xdf\xa6\x8f\x90\x8e\x02\xe3\xf8\xf4\xde\x6d\xac\x3d\x61\xcd\xc7\x12\x05\x4c\xdb\x5f\xb0\x34\xcf\xfb\xbf\x27\x07\xa9\x35\x3c\xcb\xf4\x6d\xc6\x0f\x8f\x2f\xa1\xfd\x8b\x29\xc7\x90\xa6\xb3\x91\x22\xad\x84\xd8\x64\xa9\xbe\xa3\x41\x6d\x2c\xe3\xba\xef\x2e\x6f\xfa\xee\x33\x00\x00\xff\xff\xe4\x28\x05\xe0\x2c\x01\x00\x00")
|
||||||
|
|
||||||
func _1595865249_create_emoji_reactions_tableUpSqlBytes() ([]byte, error) {
|
func _1595865249_create_emoji_reactions_tableUpSqlBytes() ([]byte, error) {
|
||||||
return bindataRead(
|
return bindataRead(
|
||||||
@ -442,8 +442,8 @@ func _1595865249_create_emoji_reactions_tableUpSql() (*asset, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "1595865249_create_emoji_reactions_table.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1595865239, 0)}
|
info := bindataFileInfo{name: "1595865249_create_emoji_reactions_table.up.sql", size: 300, mode: os.FileMode(0644), modTime: time.Unix(1595921491, 0)}
|
||||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x13, 0x28, 0xa4, 0x70, 0xf0, 0xfe, 0xd, 0xc2, 0x16, 0xc3, 0x1d, 0xbb, 0x3c, 0x1, 0xf6, 0x58, 0x69, 0x2a, 0x27, 0x21, 0xbc, 0x8b, 0xc8, 0x1a, 0xd, 0x36, 0x2d, 0x29, 0x0, 0xc3, 0xfa, 0xad}}
|
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xc5, 0x43, 0x5c, 0x3d, 0x53, 0x43, 0x2c, 0x1a, 0xa5, 0xb6, 0xbf, 0x7, 0x4, 0x5a, 0x3e, 0x40, 0x8b, 0xa4, 0x57, 0x12, 0x58, 0xbc, 0x42, 0xe2, 0xc3, 0xde, 0x76, 0x98, 0x80, 0xe2, 0xbe}}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,5 +5,6 @@ CREATE TABLE IF NOT EXISTS emoji_reactions (
|
|||||||
emoji_id INT NOT NULL,
|
emoji_id INT NOT NULL,
|
||||||
message_id VARCHAR NOT NULL,
|
message_id VARCHAR NOT NULL,
|
||||||
chat_id VARCHAR NOT NULL,
|
chat_id VARCHAR NOT NULL,
|
||||||
|
local_chat_id VARCHAR NOT NULL,
|
||||||
retracted INT DEFAULT 0
|
retracted INT DEFAULT 0
|
||||||
);
|
);
|
||||||
|
@ -407,7 +407,8 @@ func TestPersistenceEmojiReactions(t *testing.T) {
|
|||||||
ChatId: chatID,
|
ChatId: chatID,
|
||||||
Type: protobuf.EmojiReaction_SAD,
|
Type: protobuf.EmojiReaction_SAD,
|
||||||
},
|
},
|
||||||
From: from1,
|
LocalChatID: chatID,
|
||||||
|
From: from1,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Insert retracted emoji reaction
|
// Insert retracted emoji reaction
|
||||||
@ -419,7 +420,8 @@ func TestPersistenceEmojiReactions(t *testing.T) {
|
|||||||
Type: protobuf.EmojiReaction_SAD,
|
Type: protobuf.EmojiReaction_SAD,
|
||||||
Retracted: true,
|
Retracted: true,
|
||||||
},
|
},
|
||||||
From: from2,
|
LocalChatID: chatID,
|
||||||
|
From: from2,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Insert retracted emoji reaction out of pagination
|
// Insert retracted emoji reaction out of pagination
|
||||||
@ -430,7 +432,8 @@ func TestPersistenceEmojiReactions(t *testing.T) {
|
|||||||
ChatId: chatID,
|
ChatId: chatID,
|
||||||
Type: protobuf.EmojiReaction_SAD,
|
Type: protobuf.EmojiReaction_SAD,
|
||||||
},
|
},
|
||||||
From: from2,
|
LocalChatID: chatID,
|
||||||
|
From: from2,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Insert retracted emoji reaction out of pagination
|
// Insert retracted emoji reaction out of pagination
|
||||||
@ -441,7 +444,20 @@ func TestPersistenceEmojiReactions(t *testing.T) {
|
|||||||
ChatId: chatID,
|
ChatId: chatID,
|
||||||
Type: protobuf.EmojiReaction_SAD,
|
Type: protobuf.EmojiReaction_SAD,
|
||||||
},
|
},
|
||||||
From: from3,
|
LocalChatID: chatID,
|
||||||
|
From: from3,
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Wrong local chat id
|
||||||
|
require.NoError(t, p.SaveEmojiReaction(&EmojiReaction{
|
||||||
|
EmojiReaction: protobuf.EmojiReaction{
|
||||||
|
Clock: 1,
|
||||||
|
MessageId: id1,
|
||||||
|
ChatId: chatID,
|
||||||
|
Type: protobuf.EmojiReaction_LOVE,
|
||||||
|
},
|
||||||
|
LocalChatID: "wrong-chat-id",
|
||||||
|
From: from3,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
reactions, err := p.EmojiReactionsByChatID(chatID, "", 1)
|
reactions, err := p.EmojiReactionsByChatID(chatID, "", 1)
|
||||||
|
@ -54,7 +54,8 @@ func TestSignMembershipUpdate(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Encode message
|
// Encode message
|
||||||
encodedMessage := testMembershipUpdateMessageStruct.ToProtobuf()
|
encodedMessage, err := testMembershipUpdateMessageStruct.ToProtobuf()
|
||||||
|
require.NoError(t, err)
|
||||||
// Verify it
|
// Verify it
|
||||||
verifiedMessage, err := MembershipUpdateMessageFromProtobuf(encodedMessage)
|
verifiedMessage, err := MembershipUpdateMessageFromProtobuf(encodedMessage)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user