Handle identity verifications
This commit is contained in:
parent
a89f4b2d71
commit
de61ed1213
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue