diff --git a/protocol/activity_center.go b/protocol/activity_center.go index 6a228c48f..766a016ce 100644 --- a/protocol/activity_center.go +++ b/protocol/activity_center.go @@ -41,21 +41,21 @@ const ( var ErrInvalidActivityCenterNotification = errors.New("invalid activity center notification") type ActivityCenterNotification struct { - ID types.HexBytes `json:"id"` - ChatID string `json:"chatId"` - CommunityID string `json:"communityId"` - MembershipStatus ActivityCenterMembershipStatus `json:"membershipStatus"` - Name string `json:"name"` - Author string `json:"author"` - Type ActivityCenterType `json:"type"` - LastMessage *common.Message `json:"lastMessage"` - Message *common.Message `json:"message"` - ReplyMessage *common.Message `json:"replyMessage"` - Timestamp uint64 `json:"timestamp"` - Read bool `json:"read"` - Dismissed bool `json:"dismissed"` - Accepted bool `json:"accepted"` - ContactVerificationStatus verification.RequestStatus `json:"contactVerificationStatus"` + ID types.HexBytes `json:"id"` + ChatID string `json:"chatId"` + CommunityID string `json:"communityId"` + MembershipStatus ActivityCenterMembershipStatus `json:"membershipStatus"` + Name string `json:"name"` + Author string `json:"author"` + Type ActivityCenterType `json:"type"` + LastMessage *common.Message `json:"lastMessage"` + Message *common.Message `json:"message"` + ReplyMessage *common.Message `json:"replyMessage"` + Timestamp uint64 `json:"timestamp"` + Read bool `json:"read"` + Dismissed bool `json:"dismissed"` + Accepted bool `json:"accepted"` + ContactVerificationStatus verification.RequestStatus `json:"contactVerificationStatus"` } type ActivityCenterPaginationResponse struct { diff --git a/protocol/activity_center_persistence.go b/protocol/activity_center_persistence.go index 8ab0a49f7..2e2a5eac6 100644 --- a/protocol/activity_center_persistence.go +++ b/protocol/activity_center_persistence.go @@ -122,7 +122,7 @@ func (db sqlitePersistence) SaveActivityCenterNotification(notification *Activit } } - _, err = tx.Exec(`INSERT OR REPLACE INTO activity_center_notifications (id, timestamp, notification_type, chat_id, community_id, membership_status, message, reply_message, author) VALUES (?,?,?,?,?,?,?,?,?)`, notification.ID, notification.Timestamp, notification.Type, notification.ChatID, notification.CommunityID, notification.MembershipStatus, encodedMessage, encodedReplyMessage, notification.Author) + _, err = tx.Exec(`INSERT OR REPLACE INTO activity_center_notifications (id, timestamp, notification_type, chat_id, community_id, membership_status, message, reply_message, author, contact_verification_status) VALUES (?,?,?,?,?,?,?,?,?,?)`, notification.ID, notification.Timestamp, notification.Type, notification.ChatID, notification.CommunityID, notification.MembershipStatus, encodedMessage, encodedReplyMessage, notification.Author, notification.ContactVerificationStatus) return err } @@ -148,7 +148,7 @@ func (db sqlitePersistence) unmarshalActivityCenterNotificationRow(row *sql.Row) &messageBytes, &lastMessageBytes, &replyMessageBytes, - ¬ification.ContactVerificationStatus, + ¬ification.ContactVerificationStatus, &name, &author) @@ -710,12 +710,11 @@ func (db sqlitePersistence) UpdateActivityCenterNotificationMessage(id types.Hex } func (db sqlitePersistence) UpdateActivityCenterNotificationContactVerificationStatus(id types.HexBytes, status verification.RequestStatus) error { - _, err := db.db.Exec(`UPDATE activity_center_notifications SET contact_verification_status = ? WHERE id = ?`, status, id) - return err + _, err := db.db.Exec(`UPDATE activity_center_notifications SET contact_verification_status = ? WHERE id = ?`, status, id) + return err } - func (db sqlitePersistence) AcceptActivityCenterNotificationsForInvitesFromUser(userPublicKey string) ([]*ActivityCenterNotification, error) { var tx *sql.Tx var err error diff --git a/protocol/common/message.go b/protocol/common/message.go index 086f65c41..de10190d6 100644 --- a/protocol/common/message.go +++ b/protocol/common/message.go @@ -64,7 +64,7 @@ type ContactVerificationState int const ( ContactVerificationStatePending ContactVerificationState = iota + 1 ContactVerificationStateAccepted - ContactVerificationStateDismissed + ContactVerificationStateDeclined ) type CommandParameters struct { @@ -205,81 +205,81 @@ func (m *Message) MarshalJSON() ([]byte, error) { URL string `json:"url"` } item := struct { - ID string `json:"id"` - WhisperTimestamp uint64 `json:"whisperTimestamp"` - From string `json:"from"` - Alias string `json:"alias"` - Identicon string `json:"identicon"` - Seen bool `json:"seen"` - OutgoingStatus string `json:"outgoingStatus,omitempty"` - QuotedMessage *QuotedMessage `json:"quotedMessage"` - RTL bool `json:"rtl"` - ParsedText json.RawMessage `json:"parsedText,omitempty"` - LineCount int `json:"lineCount"` - Text string `json:"text"` - ChatID string `json:"chatId"` - LocalChatID string `json:"localChatId"` - Clock uint64 `json:"clock"` - Replace string `json:"replace"` - ResponseTo string `json:"responseTo"` - New bool `json:"new,omitempty"` - EnsName string `json:"ensName"` - DisplayName string `json:"displayName"` - Image string `json:"image,omitempty"` - Audio string `json:"audio,omitempty"` - AudioDurationMs uint64 `json:"audioDurationMs,omitempty"` - CommunityID string `json:"communityId,omitempty"` - Sticker *StickerAlias `json:"sticker,omitempty"` - CommandParameters *CommandParameters `json:"commandParameters,omitempty"` - GapParameters *GapParameters `json:"gapParameters,omitempty"` - Timestamp uint64 `json:"timestamp"` - ContentType protobuf.ChatMessage_ContentType `json:"contentType"` - MessageType protobuf.MessageType `json:"messageType"` - Mentions []string `json:"mentions,omitempty"` - Mentioned bool `json:"mentioned,omitempty"` - Links []string `json:"links,omitempty"` - EditedAt uint64 `json:"editedAt,omitempty"` - Deleted bool `json:"deleted,omitempty"` - DeletedForMe bool `json:"deletedForMe,omitempty"` - ContactRequestState ContactRequestState `json:"contactRequestState,omitempty"` - ContactVerificationState ContactVerificationState `json:"contactVerificationState,omitempty"` - DiscordMessage *protobuf.DiscordMessage `json:"discordMessage,omitempty"` + ID string `json:"id"` + WhisperTimestamp uint64 `json:"whisperTimestamp"` + From string `json:"from"` + Alias string `json:"alias"` + Identicon string `json:"identicon"` + Seen bool `json:"seen"` + OutgoingStatus string `json:"outgoingStatus,omitempty"` + QuotedMessage *QuotedMessage `json:"quotedMessage"` + RTL bool `json:"rtl"` + ParsedText json.RawMessage `json:"parsedText,omitempty"` + LineCount int `json:"lineCount"` + Text string `json:"text"` + ChatID string `json:"chatId"` + LocalChatID string `json:"localChatId"` + Clock uint64 `json:"clock"` + Replace string `json:"replace"` + ResponseTo string `json:"responseTo"` + New bool `json:"new,omitempty"` + EnsName string `json:"ensName"` + DisplayName string `json:"displayName"` + Image string `json:"image,omitempty"` + Audio string `json:"audio,omitempty"` + AudioDurationMs uint64 `json:"audioDurationMs,omitempty"` + CommunityID string `json:"communityId,omitempty"` + Sticker *StickerAlias `json:"sticker,omitempty"` + CommandParameters *CommandParameters `json:"commandParameters,omitempty"` + GapParameters *GapParameters `json:"gapParameters,omitempty"` + Timestamp uint64 `json:"timestamp"` + ContentType protobuf.ChatMessage_ContentType `json:"contentType"` + MessageType protobuf.MessageType `json:"messageType"` + Mentions []string `json:"mentions,omitempty"` + Mentioned bool `json:"mentioned,omitempty"` + Links []string `json:"links,omitempty"` + EditedAt uint64 `json:"editedAt,omitempty"` + Deleted bool `json:"deleted,omitempty"` + DeletedForMe bool `json:"deletedForMe,omitempty"` + ContactRequestState ContactRequestState `json:"contactRequestState,omitempty"` + ContactVerificationState ContactVerificationState `json:"contactVerificationState,omitempty"` + DiscordMessage *protobuf.DiscordMessage `json:"discordMessage,omitempty"` }{ - ID: m.ID, - WhisperTimestamp: m.WhisperTimestamp, - From: m.From, - Alias: m.Alias, - Identicon: m.Identicon, - Seen: m.Seen, - OutgoingStatus: m.OutgoingStatus, - QuotedMessage: m.QuotedMessage, - RTL: m.RTL, - ParsedText: m.ParsedText, - LineCount: m.LineCount, - Text: m.Text, - Replace: m.Replace, - ChatID: m.ChatId, - LocalChatID: m.LocalChatID, - Clock: m.Clock, - ResponseTo: m.ResponseTo, - New: m.New, - EnsName: m.EnsName, - DisplayName: m.DisplayName, - Image: m.ImageLocalURL, - Audio: m.AudioLocalURL, - CommunityID: m.CommunityID, - Timestamp: m.Timestamp, - ContentType: m.ContentType, - Mentions: m.Mentions, - Mentioned: m.Mentioned, - Links: m.Links, - MessageType: m.MessageType, - CommandParameters: m.CommandParameters, - GapParameters: m.GapParameters, - EditedAt: m.EditedAt, - Deleted: m.Deleted, - DeletedForMe: m.DeletedForMe, - ContactRequestState: m.ContactRequestState, + ID: m.ID, + WhisperTimestamp: m.WhisperTimestamp, + From: m.From, + Alias: m.Alias, + Identicon: m.Identicon, + Seen: m.Seen, + OutgoingStatus: m.OutgoingStatus, + QuotedMessage: m.QuotedMessage, + RTL: m.RTL, + ParsedText: m.ParsedText, + LineCount: m.LineCount, + Text: m.Text, + Replace: m.Replace, + ChatID: m.ChatId, + LocalChatID: m.LocalChatID, + Clock: m.Clock, + ResponseTo: m.ResponseTo, + New: m.New, + EnsName: m.EnsName, + DisplayName: m.DisplayName, + Image: m.ImageLocalURL, + Audio: m.AudioLocalURL, + CommunityID: m.CommunityID, + Timestamp: m.Timestamp, + ContentType: m.ContentType, + Mentions: m.Mentions, + Mentioned: m.Mentioned, + Links: m.Links, + MessageType: m.MessageType, + CommandParameters: m.CommandParameters, + GapParameters: m.GapParameters, + EditedAt: m.EditedAt, + Deleted: m.Deleted, + DeletedForMe: m.DeletedForMe, + ContactRequestState: m.ContactRequestState, ContactVerificationState: m.ContactVerificationState, } if sticker := m.GetSticker(); sticker != nil { diff --git a/protocol/messenger_contact_verification.go b/protocol/messenger_contact_verification.go index 2c31ab50c..766a4f468 100644 --- a/protocol/messenger_contact_verification.go +++ b/protocol/messenger_contact_verification.go @@ -279,13 +279,13 @@ func (m *Messenger) AcceptContactVerificationRequest(ctx context.Context, id str resp.AddMessage(chatMessage) if notification != nil { - // TODO: Should we update only the message or only the notification or both? - err := m.persistence.UpdateActivityCenterNotificationContactVerificationStatus(notification.ID, verification.RequestStatusACCEPTED) - if err != nil { - return nil, err - } + // TODO: Should we update only the message or only the notification or both? + err := m.persistence.UpdateActivityCenterNotificationContactVerificationStatus(notification.ID, verification.RequestStatusACCEPTED) + if err != nil { + return nil, err + } - notification.ContactVerificationStatus = verification.RequestStatusACCEPTED + notification.ContactVerificationStatus = verification.RequestStatusACCEPTED message := notification.Message message.ContactVerificationState = common.ContactVerificationStateAccepted err = m.persistence.UpdateActivityCenterNotificationMessage(notification.ID, message) @@ -416,31 +416,31 @@ func (m *Messenger) VerifiedUntrustworthy(ctx context.Context, contactID string) return nil } -func (m *Messenger) DeclineContactVerificationRequest(ctx context.Context, id string) error { +func (m *Messenger) DeclineContactVerificationRequest(ctx context.Context, id string) (*MessengerResponse, error) { verifRequest, err := m.verificationDatabase.GetVerificationRequest(id) if err != nil { - return err + return nil, err } if verifRequest == nil { m.logger.Error("could not find verification request with id", zap.String("id", id)) - return verification.ErrVerificationRequestNotFound + return nil, verification.ErrVerificationRequestNotFound } contact, ok := m.allContacts.Load(verifRequest.From) if !ok || !contact.Added || !contact.HasAddedUs { - return errors.New("must be a mutual contact") + return nil, errors.New("must be a mutual contact") } if verifRequest == nil { - return errors.New("no contact verification found") + return nil, errors.New("no contact verification found") } chat, ok := m.allChats.Load(verifRequest.From) if !ok { publicKey, err := contact.PublicKey() if err != nil { - return err + return nil, err } chat = OneToOneFromPublicKey(publicKey, m.getTimesource()) // We don't want to show the chat to the user @@ -454,12 +454,16 @@ func (m *Messenger) DeclineContactVerificationRequest(ctx context.Context, id st verifRequest.RepliedAt = clock err = m.verificationDatabase.SaveVerificationRequest(verifRequest) if err != nil { - return err + return nil, err } + response := &MessengerResponse{} + + response.AddVerificationRequest(verifRequest) + err = m.SyncVerificationRequest(context.Background(), verifRequest) if err != nil { - return err + return nil, err } request := &protobuf.DeclineContactVerification{ @@ -469,7 +473,7 @@ func (m *Messenger) DeclineContactVerificationRequest(ctx context.Context, id st encodedMessage, err := proto.Marshal(request) if err != nil { - return err + return nil, err } _, err = m.dispatchMessage(ctx, common.RawMessage{ @@ -480,10 +484,38 @@ func (m *Messenger) DeclineContactVerificationRequest(ctx context.Context, id st }) if err != nil { - return err + return nil, err } - return m.verificationDatabase.DeclineContactVerificationRequest(verifRequest.From) + err = m.verificationDatabase.DeclineContactVerificationRequest(id) + if err != nil { + return nil, err + } + + notification, err := m.persistence.GetActivityCenterNotificationByID(types.FromHex(id)) + if err != nil { + return nil, err + } + + if notification != nil { + // TODO: Should we update only the message or only the notification or both? + err := m.persistence.UpdateActivityCenterNotificationContactVerificationStatus(notification.ID, verification.RequestStatusDECLINED) + if err != nil { + return nil, err + } + + notification.ContactVerificationStatus = verification.RequestStatusDECLINED + message := notification.Message + message.ContactVerificationState = common.ContactVerificationStateDeclined + err = m.persistence.UpdateActivityCenterNotificationMessage(notification.ID, message) + if err != nil { + return nil, err + } + response.AddActivityCenterNotification(notification) + response.AddMessage(message) + } + + return response, nil } func (m *Messenger) MarkAsTrusted(ctx context.Context, contactID string) error { @@ -728,7 +760,7 @@ func (m *Messenger) HandleDeclineContactVerification(state *ReceivedMessageState return errors.New("must be a mutual contact") } - persistedVR, err := m.verificationDatabase.GetVerificationRequestSentTo(contactID) + persistedVR, err := m.verificationDatabase.GetVerificationRequest(request.Id) if err != nil { m.logger.Debug("Error obtaining verification request", zap.Error(err)) return err @@ -765,9 +797,17 @@ func (m *Messenger) HandleDeclineContactVerification(state *ReceivedMessageState state.AllVerificationRequests = append(state.AllVerificationRequests, persistedVR) - // TODO: create or update activity center notification + msg, err := m.persistence.MessageByID(request.Id) + if err != nil { + return err + } - return nil + if msg != nil { + msg.ContactVerificationState = common.ContactVerificationStateDeclined + state.Response.AddMessage(msg) + } + + return m.createContactVerificationNotification(contact, state, persistedVR, msg) } func (m *Messenger) HandleContactVerificationTrusted(state *ReceivedMessageState, request protobuf.ContactVerificationTrusted) error { diff --git a/protocol/messenger_contact_verification_test.go b/protocol/messenger_contact_verification_test.go index 3307e194e..7371b6cc7 100644 --- a/protocol/messenger_contact_verification_test.go +++ b/protocol/messenger_contact_verification_test.go @@ -162,7 +162,7 @@ func (s *MessengerVerificationRequests) mutualContact(theirMessenger *Messenger) } -func (s *MessengerVerificationRequests) TestVerificationRequests() { +func (s *MessengerVerificationRequests) TestAcceptVerificationRequests() { theirMessenger := s.newMessenger(s.shh) _, err := theirMessenger.Start() s.Require().NoError(err) @@ -241,6 +241,100 @@ func (s *MessengerVerificationRequests) TestVerificationRequests() { s.Require().Equal(common.ContactVerificationStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) } +func (s *MessengerVerificationRequests) TestDeclineVerificationRequests() { + theirMessenger := s.newMessenger(s.shh) + _, err := theirMessenger.Start() + s.Require().NoError(err) + + s.mutualContact(theirMessenger) + + theirPk := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) + challenge := "challenge" + + resp, err := s.m.SendContactVerificationRequest(context.Background(), theirPk, challenge) + s.Require().NoError(err) + s.Require().Len(resp.VerificationRequests, 1) + verificationRequestID := resp.VerificationRequests[0].ID + + s.Require().Len(resp.Messages(), 1) + s.Require().Equal(challenge, resp.Messages()[0].Text) + s.Require().Equal(common.ContactVerificationStatePending, resp.Messages()[0].ContactVerificationState) + + // Wait for the message to reach its destination + resp, err = WaitOnMessengerResponse( + theirMessenger, + func(r *MessengerResponse) bool { + return len(r.VerificationRequests) > 0 && len(r.ActivityCenterNotifications()) > 0 + }, + "no messages", + ) + s.Require().NoError(err) + s.Require().Len(resp.VerificationRequests, 1) + s.Require().Equal(resp.VerificationRequests[0].ID, verificationRequestID) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Type, ActivityCenterNotificationTypeContactVerification) + s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusPENDING) + + s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) + s.Require().Equal(challenge, resp.ActivityCenterNotifications()[0].Message.Text) + s.Require().Equal(common.ContactVerificationStatePending, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) + s.Require().Len(resp.Messages(), 1) + s.Require().Equal(challenge, resp.Messages()[0].Text) + s.Require().Equal(common.ContactVerificationStatePending, resp.Messages()[0].ContactVerificationState) + + // Make sure it's stored and retrieved correctly + notifications, err := theirMessenger.UnreadActivityCenterNotifications("", 4, ActivityCenterNotificationTypeContactVerification) + s.Require().NoError(err) + s.Require().Len(notifications.Notifications, 1) + s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusPENDING) + s.Require().Equal(common.ContactVerificationStatePending, notifications.Notifications[0].Message.ContactVerificationState) + + resp, err = theirMessenger.DeclineContactVerificationRequest(context.Background(), verificationRequestID) + + s.Require().NoError(err) + + s.Require().NotNil(resp) + + s.Require().Len(resp.VerificationRequests, 1) + s.Require().Equal(resp.VerificationRequests[0].ID, verificationRequestID) + s.Require().Equal(resp.VerificationRequests[0].RequestStatus, verification.RequestStatusDECLINED) + s.Require().NotEmpty(resp.VerificationRequests[0].RepliedAt) + + s.Require().Len(resp.ActivityCenterNotifications(), 1) + s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) + + s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusDECLINED) + s.Require().Equal(common.ContactVerificationStateDeclined, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) + s.Require().Len(resp.Messages(), 1) + s.Require().Equal(common.ContactVerificationStateDeclined, resp.Messages()[0].ContactVerificationState) + + // Make sure it's stored and retrieved correctly + notifications, err = theirMessenger.UnreadActivityCenterNotifications("", 4, ActivityCenterNotificationTypeContactVerification) + s.Require().NoError(err) + s.Require().Len(notifications.Notifications, 1) + s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusDECLINED) + s.Require().Equal(common.ContactVerificationStateDeclined, notifications.Notifications[0].Message.ContactVerificationState) + + // Wait for the message to reach its destination + resp, err = WaitOnMessengerResponse( + s.m, + func(r *MessengerResponse) bool { + return len(r.VerificationRequests) > 0 + }, + "no messages", + ) + s.Require().NoError(err) + s.Require().Len(resp.VerificationRequests, 1) + s.Require().Equal(resp.VerificationRequests[0].ID, verificationRequestID) + + s.Require().Len(resp.Messages(), 1) + s.Require().Equal(common.ContactVerificationStateDeclined, resp.Messages()[0].ContactVerificationState) + + s.Require().Len(resp.ActivityCenterNotifications(), 1) + s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) + s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusDECLINED) + s.Require().Equal(common.ContactVerificationStateDeclined, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) +} + func (s *MessengerVerificationRequests) TearDownTest() { s.Require().NoError(s.m.Shutdown()) } diff --git a/protocol/migrations/migrations.go b/protocol/migrations/migrations.go index f73e71f7a..fde45eb37 100644 --- a/protocol/migrations/migrations.go +++ b/protocol/migrations/migrations.go @@ -66,7 +66,7 @@ // 1665079662_add_spectated_column_in_communities.up.sql (86B) // 1665479047_add_community_id_in_notifications.up.sql (169B) // 1665484435_add_encrypted_messages.up.sql (402B) -// 1665560200_add_contact_verification_individual.up.sql (474B) +// 1665560200_add_contact_verification_individual.up.sql (509B) // README.md (554B) // doc.go (850B) @@ -1457,7 +1457,7 @@ func _1665484435_add_encrypted_messagesUpSql() (*asset, error) { return a, nil } -var __1665560200_add_contact_verification_individualUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x8f\xc1\x6a\xf3\x30\x10\x84\xef\x7a\x8a\x3d\xfe\x3f\xf4\xd0\xbb\x4f\xaa\x2d\x83\xa9\x22\x07\x47\x86\xe4\x24\x84\xbc\x49\x05\x8e\x94\x4a\x6b\x43\xdf\xbe\xc4\x49\xd3\x06\x5a\x4a\x8f\xd2\xce\x7c\x33\xc3\xa5\x16\x1d\x68\xfe\x24\x05\x4c\x19\x93\x39\x62\xce\xf6\x80\x19\x78\x55\x41\xd9\xca\x7e\xa5\xc0\xc5\x40\xd6\x91\x99\x31\xf9\xbd\x77\x96\x7c\x0c\x26\x93\xa5\x29\x43\xa3\x74\xc1\xbe\x52\xac\x23\x3f\x7b\x7a\x33\x0e\x03\x61\x32\x21\xd2\xcd\xf4\x17\x2a\x54\xa2\xe6\xbd\xd4\xf0\x58\x30\x56\x76\x82\x6b\x71\x4d\x68\x6a\x50\xad\x06\xb1\x6d\x36\x7a\x03\x77\xf6\x84\xaf\x13\x66\xca\xc6\x87\xc1\xcf\x7e\x98\xec\x08\xff\x18\xc0\x3e\xc5\xa3\x39\xef\x03\x2d\xb6\xfa\x81\x01\x50\xbc\x7f\xbb\x17\x3b\x8e\x18\x0e\xb8\xfc\x2c\x01\xaa\x97\xf2\x7c\xba\x42\x71\x30\x96\x96\x66\x1f\xc7\xcf\x8a\x17\x59\x3e\xc5\x90\xf1\x86\x4c\x78\x1a\xfd\x6f\xae\x9f\xd6\x7f\xaf\xf6\xc3\xa5\xde\xba\x6b\x56\xbc\xdb\xc1\xb3\xd8\x41\xab\xa0\x6c\x55\x2d\x9b\x52\x43\x27\xd6\x92\x97\x82\xfd\x2f\xd8\x7b\x00\x00\x00\xff\xff\xe0\x53\x96\x59\xda\x01\x00\x00") +var __1665560200_add_contact_verification_individualUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x90\xc1\x6a\x03\x21\x10\x86\xef\x3e\xc5\x1c\x5b\xe8\xa1\xf7\x3d\xd9\x5d\x03\x4b\x8d\x1b\x8c\x81\xe4\x24\xe2\x4e\x52\x61\xa3\xa9\xce\x06\xfa\xf6\x25\xc9\x36\x6d\x20\xa5\xf4\xa8\xf3\xfd\x9f\xe3\xcf\xa5\x11\x1a\x0c\x7f\x91\x02\xc6\x82\xd9\xee\xb1\x14\xb7\xc3\x02\xbc\x69\xa0\xee\xe4\x6a\xae\xc0\xa7\x48\xce\x93\x3d\x62\x0e\xdb\xe0\x1d\x85\x14\x6d\x21\x47\x63\x81\x56\x99\x8a\xfd\xb4\x38\x4f\xe1\x18\xe8\xc3\x7a\x8c\x84\xd9\xc6\x44\xd7\xd0\x7f\xac\xd0\x88\x19\x5f\x49\x03\xcf\x15\x63\x8d\xee\x16\x93\xff\x06\xcf\xf8\x3e\x62\xa1\x52\x31\x56\x6b\xc1\x8d\x98\xa0\x76\x06\xaa\x33\x20\xd6\xed\xd2\x2c\xef\x47\x6c\x88\x7d\x38\x86\x7e\x74\x03\x3c\x30\x80\x6d\x4e\x7b\x7b\xaa\x00\x8c\x58\x9b\x27\x06\x40\xe9\xf6\xec\xdf\xdc\x30\x60\xdc\xe1\xf9\xe6\xfc\x80\x5a\x49\x79\x1a\x4d\x52\xec\xad\xa3\xf3\xf2\x5f\xc3\xef\x5f\x5c\xb0\x72\x48\xb1\xe0\x55\x99\xf1\x30\x84\xbf\x52\xbf\x15\x74\x9f\x0e\xfd\x65\xbd\x85\x6e\xe7\x5c\x6f\xe0\x55\x6c\xa0\x53\x50\x77\x6a\x26\xdb\xda\x80\x16\x0b\xc9\x6b\xc1\x1e\x2b\xf6\x19\x00\x00\xff\xff\xfa\x97\x1b\xc5\xfd\x01\x00\x00") func _1665560200_add_contact_verification_individualUpSqlBytes() ([]byte, error) { return bindataRead( @@ -1472,8 +1472,8 @@ func _1665560200_add_contact_verification_individualUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1665560200_add_contact_verification_individual.up.sql", size: 474, mode: os.FileMode(0644), modTime: time.Unix(1666784614, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1a, 0x9e, 0x80, 0x24, 0xd3, 0xd5, 0x19, 0x52, 0x28, 0x9f, 0xe6, 0x60, 0x3a, 0xd9, 0x8e, 0x32, 0x86, 0x7b, 0x43, 0x35, 0x9e, 0x21, 0x6e, 0x2b, 0xe5, 0x86, 0xf3, 0xcf, 0xe4, 0x6b, 0x91, 0x2f}} + info := bindataFileInfo{name: "1665560200_add_contact_verification_individual.up.sql", size: 509, mode: os.FileMode(0644), modTime: time.Unix(1666788871, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc5, 0xbb, 0x61, 0xfd, 0xbf, 0x33, 0x1d, 0x4e, 0x5f, 0xbd, 0x86, 0x42, 0xb0, 0x6c, 0xf7, 0x39, 0x19, 0x6e, 0x72, 0x35, 0xfd, 0x1b, 0xd6, 0xbd, 0xf6, 0x81, 0x21, 0xc4, 0xaa, 0x6, 0x62, 0x40}} return a, nil } diff --git a/protocol/migrations/sqlite/1665560200_add_contact_verification_individual.up.sql b/protocol/migrations/sqlite/1665560200_add_contact_verification_individual.up.sql index ccc3359df..0adc990fc 100644 --- a/protocol/migrations/sqlite/1665560200_add_contact_verification_individual.up.sql +++ b/protocol/migrations/sqlite/1665560200_add_contact_verification_individual.up.sql @@ -1,6 +1,8 @@ ALTER TABLE user_messages ADD COLUMN contact_verification_status INT; ALTER TABLE activity_center_notifications ADD COLUMN contact_verification_status INT DEFAULT 0; +DROP TABLE verification_requests; + CREATE TABLE IF NOT EXISTS verification_requests_individual ( from_user TEXT, to_user TEXT, diff --git a/protocol/verification/persistence.go b/protocol/verification/persistence.go index b1d38c270..c1a7de083 100644 --- a/protocol/verification/persistence.go +++ b/protocol/verification/persistence.go @@ -40,7 +40,7 @@ const ( ) type Request struct { - ID string `json:"id"` + ID string `json:"id"` From string `json:"from"` To string `json:"to"` Challenge string `json:"challenge"` @@ -72,7 +72,7 @@ func (p *Persistence) GetVerificationRequests() ([]Request, error) { func (p *Persistence) GetVerificationRequest(id string) (*Request, error) { var vr Request err := p.db.QueryRow(`SELECT id, from_user, to_user, challenge, response, requested_at, verification_status, replied_at FROM verification_requests_individual WHERE id = ?`, id).Scan( - &vr.ID, + &vr.ID, &vr.From, &vr.To, &vr.Challenge, @@ -107,7 +107,7 @@ func (p *Persistence) GetReceivedVerificationRequests(myPublicKey string) ([]*Re var vr Request err := rows.Scan( - &vr.ID, + &vr.ID, &vr.From, &vr.To, &vr.Challenge, @@ -129,7 +129,7 @@ func (p *Persistence) GetReceivedVerificationRequests(myPublicKey string) ([]*Re func (p *Persistence) GetVerificationRequestSentTo(contactID string) (*Request, error) { var vr Request err := p.db.QueryRow(`SELECT id, from_user, to_user, challenge, response, requested_at, verification_status, replied_at FROM verification_requests_individual WHERE to_user = ?`, contactID).Scan( - &vr.ID, + &vr.ID, &vr.From, &vr.To, &vr.Challenge, diff --git a/protocol/verification/persistence_test.go b/protocol/verification/persistence_test.go index f6a755699..06a3005ff 100644 --- a/protocol/verification/persistence_test.go +++ b/protocol/verification/persistence_test.go @@ -34,7 +34,7 @@ func (s *PersistenceSuite) SetupTest() { func (s *PersistenceSuite) TestVerificationRequests() { request := &Request{ - ID: "0xabc", + ID: "0xabc", From: "0x01", To: "0x02", Challenge: "ABC", @@ -46,30 +46,32 @@ func (s *PersistenceSuite) TestVerificationRequests() { // Test Insert err := s.db.SaveVerificationRequest(request) - s.NoError(err) + s.Require().NoError(err) // Test Found dbRequest, err := s.db.GetVerificationRequest("0xabc") - s.NoError(err) - s.Equal(request, dbRequest) + s.Require().NoError(err) + s.Require().Equal(request, dbRequest) // Test Not Found - dbRequest2, err := s.db.GetVerificationRequestFrom("0xdef") - s.NoError(err) - s.Nil(dbRequest2) + dbRequest2, err := s.db.GetVerificationRequest("0xdef") + s.Require().NoError(err) + s.Require().Nil(dbRequest2) // Test Accept - err = s.db.AcceptContactVerificationRequest("0x01", "XYZ") - s.NoError(err) + err = s.db.AcceptContactVerificationRequest("0xabc", "XYZ") + s.Require().NoError(err) - dbRequest, err = s.db.GetVerificationRequestFrom("0x01") - s.NoError(err) - s.Equal(RequestStatusACCEPTED, dbRequest.RequestStatus) - s.Equal("XYZ", dbRequest.Response) - s.NotEqual(time.Unix(0, 0), dbRequest.RepliedAt) + dbRequest, err = s.db.GetVerificationRequest("0xabc") + s.Require().NoError(err) + s.Require().NotNil(dbRequest) + s.Require().Equal(RequestStatusACCEPTED, dbRequest.RequestStatus) + s.Require().Equal("XYZ", dbRequest.Response) + s.Require().NotEqual(time.Unix(0, 0), dbRequest.RepliedAt) // Test Decline request = &Request{ + ID: "0x01", From: "0x03", To: "0x02", Challenge: "ABC", @@ -82,51 +84,14 @@ func (s *PersistenceSuite) TestVerificationRequests() { err = s.db.SaveVerificationRequest(request) s.NoError(err) - err = s.db.DeclineContactVerificationRequest("0x03") + err = s.db.DeclineContactVerificationRequest("0x01") s.NoError(err) - dbRequest, err = s.db.GetVerificationRequestFrom("0x03") + dbRequest, err = s.db.GetVerificationRequest("0x01") s.NoError(err) s.Equal(RequestStatusDECLINED, dbRequest.RequestStatus) s.NotEqual(time.Unix(0, 0), dbRequest.RepliedAt) - // Test Upsert fails because of older record - ogDbRequestStatus := dbRequest.RequestStatus - dbRequest.RequestStatus = RequestStatusPENDING - shouldSync, err := s.db.UpsertVerificationRequest(dbRequest) - s.NoError(err) - s.False(shouldSync) - - dbRequest.RequestStatus = ogDbRequestStatus - dbRequest2, err = s.db.GetVerificationRequestFrom("0x03") - s.NoError(err) - s.Equal(dbRequest, dbRequest2) - - // Test upsert success (update) - dbRequest2.RequestStatus = RequestStatusPENDING - dbRequest2.RepliedAt = dbRequest2.RepliedAt + 100 - shouldSync, err = s.db.UpsertVerificationRequest(dbRequest2) - s.NoError(err) - s.True(shouldSync) - - // Test upsert success (insert) - verifReq := &Request{ - From: "0x0A", - To: "0x0B", - Challenge: "123", - Response: "456", - RequestedAt: uint64(time.Now().Unix()), - RepliedAt: uint64(time.Now().Unix()), - RequestStatus: RequestStatusPENDING, - } - - shouldSync, err = s.db.UpsertVerificationRequest(verifReq) - s.NoError(err) - s.True(shouldSync) - - dbRequest, err = s.db.GetVerificationRequestFrom("0x0A") - s.NoError(err) - s.Equal(verifReq.To, dbRequest.To) } func (s *PersistenceSuite) TestTrustStatus() { diff --git a/services/ext/api.go b/services/ext/api.go index 9153a582a..db1daaf41 100644 --- a/services/ext/api.go +++ b/services/ext/api.go @@ -797,7 +797,7 @@ func (api *PublicAPI) AcceptContactVerificationRequest(ctx context.Context, cont return api.service.messenger.AcceptContactVerificationRequest(ctx, contactID, response) } -func (api *PublicAPI) DeclineContactVerificationRequest(ctx context.Context, contactID string) error { +func (api *PublicAPI) DeclineContactVerificationRequest(ctx context.Context, contactID string) (*protocol.MessengerResponse, error) { return api.service.messenger.DeclineContactVerificationRequest(ctx, contactID) }