Support outgoing contact requests (#3120)
* Outgoing contact requests * Test fix * Test fix * Fixes * Bugfixes * Bugfixes * Almost there * Removed the activity center notification * Test update * Almost ready * Fixes * Fixes
This commit is contained in:
parent
78c677742e
commit
27730057d0
|
@ -95,7 +95,7 @@ func (db sqlitePersistence) SaveActivityCenterNotification(notification *Activit
|
|||
|
||||
if notification.Type == ActivityCenterNotificationTypeNewOneToOne ||
|
||||
notification.Type == ActivityCenterNotificationTypeNewPrivateGroupChat {
|
||||
// Delete other notifications so it pop us again if not currently dismissed
|
||||
// Delete other notifications, so it pops us again if it was not dismissed
|
||||
_, err = tx.Exec(`DELETE FROM activity_center_notifications WHERE id = ? AND (dismissed OR accepted)`, notification.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -871,12 +871,11 @@ func (db sqlitePersistence) ActiveContactRequestNotification(contactID string) (
|
|||
}
|
||||
|
||||
func (db sqlitePersistence) RemoveAllContactRequestActivityCenterNotifications(chatID string) error {
|
||||
_, err := db.db.Exec(`
|
||||
DELETE FROM activity_center_notifications
|
||||
WHERE
|
||||
chat_id = ?
|
||||
AND notification_type = ?
|
||||
`, chatID, ActivityCenterNotificationTypeContactRequest)
|
||||
_, err := db.db.Exec(
|
||||
`DELETE FROM activity_center_notifications WHERE chat_id = ? AND notification_type = ?`,
|
||||
chatID,
|
||||
ActivityCenterNotificationTypeContactRequest,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -3781,7 +3781,7 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte
|
|||
logger.Debug("Handling AcceptContactRequest")
|
||||
message := msg.ParsedMessage.Interface().(protobuf.AcceptContactRequest)
|
||||
m.outputToCSV(msg.TransportMessage.Timestamp, msg.ID, senderID, filter.Topic, filter.ChatID, msg.Type, message)
|
||||
err = m.HandleAcceptContactRequest(messageState, message)
|
||||
err = m.HandleAcceptContactRequest(messageState, message, senderID)
|
||||
if err != nil {
|
||||
logger.Warn("failed to handle AcceptContactRequest", zap.Error(err))
|
||||
allMessagesProcessed = false
|
||||
|
|
|
@ -270,7 +270,7 @@ func (s *MessengerContactRequestSuite) TestReceiveAndDismissContactRequest() {
|
|||
s.Require().Equal(contactRequests[0].ContactRequestState, common.ContactRequestStatePending)
|
||||
|
||||
// Dismiss contact request, receiver side
|
||||
resp, err = theirMessenger.DismissContactRequest(context.Background(), &requests.DismissContactRequest{ID: types.Hex2Bytes(contactRequests[0].ID)})
|
||||
resp, err = theirMessenger.DeclineContactRequest(context.Background(), &requests.DeclineContactRequest{ID: types.Hex2Bytes(contactRequests[0].ID)})
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Check the contact state is correctly set
|
||||
|
@ -427,7 +427,7 @@ func (s *MessengerContactRequestSuite) TestReceiveAcceptAndRetractContactRequest
|
|||
mutualContacts = s.m.MutualContacts()
|
||||
s.Require().Len(mutualContacts, 1)
|
||||
|
||||
resp, err = s.m.RetractContactRequest(&requests.RetractContactRequest{ContactID: types.Hex2Bytes(contactID)})
|
||||
resp, err = s.m.RetractContactRequest(&requests.RetractContactRequest{ID: types.Hex2Bytes(contactID)})
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(resp)
|
||||
s.Require().Len(resp.Contacts, 1)
|
||||
|
@ -681,7 +681,7 @@ func (s *MessengerContactRequestSuite) TestAcceptLatestContactRequestForContact(
|
|||
s.Require().Len(resp.Messages(), 1)
|
||||
s.Require().Equal(common.ContactRequestStatePending, resp.Messages()[0].ContactRequestState)
|
||||
|
||||
// Make sure it's not returned as coming from us
|
||||
// Make sure it's not returned
|
||||
contactRequests, _, err := s.m.PendingContactRequests("", 10)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(contactRequests, 0)
|
||||
|
@ -1038,7 +1038,7 @@ func (s *MessengerContactRequestSuite) TestReceiveMultipleLegacy() {
|
|||
|
||||
// Remove contact
|
||||
|
||||
_, err = s.m.RetractContactRequest(&requests.RetractContactRequest{ContactID: types.Hex2Bytes(contactID)})
|
||||
_, err = s.m.RetractContactRequest(&requests.RetractContactRequest{ID: types.Hex2Bytes(contactID)})
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Wait for the message to reach its destination
|
||||
|
@ -1277,7 +1277,7 @@ func (s *MessengerContactRequestSuite) TestPairedDevicesRemoveContact() {
|
|||
s.Require().Len(resp.Contacts, 1)
|
||||
s.Require().True(resp.Contacts[0].mutual())
|
||||
|
||||
resp, err = alice1.RetractContactRequest(&requests.RetractContactRequest{ContactID: types.Hex2Bytes(bob.myHexIdentity())})
|
||||
resp, err = alice1.RetractContactRequest(&requests.RetractContactRequest{ID: types.Hex2Bytes(bob.myHexIdentity())})
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(resp)
|
||||
s.Require().Len(resp.Contacts, 1)
|
||||
|
@ -1603,7 +1603,7 @@ func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsCorrectOrd
|
|||
s.Require().Len(resp.Contacts, 1)
|
||||
s.Require().True(resp.Contacts[0].mutual())
|
||||
|
||||
_, err = alice1.RetractContactRequest(&requests.RetractContactRequest{ContactID: types.Hex2Bytes(bob.myHexIdentity())})
|
||||
_, err = alice1.RetractContactRequest(&requests.RetractContactRequest{ID: types.Hex2Bytes(bob.myHexIdentity())})
|
||||
s.Require().NoError(err)
|
||||
|
||||
// adds bob again to her device
|
||||
|
@ -1689,7 +1689,7 @@ func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsWrongOrder
|
|||
s.Require().Len(resp.Contacts, 1)
|
||||
s.Require().True(resp.Contacts[0].mutual())
|
||||
|
||||
_, err = alice1.RetractContactRequest(&requests.RetractContactRequest{ContactID: types.Hex2Bytes(bob.myHexIdentity())})
|
||||
_, err = alice1.RetractContactRequest(&requests.RetractContactRequest{ID: types.Hex2Bytes(bob.myHexIdentity())})
|
||||
s.Require().NoError(err)
|
||||
|
||||
// adds bob again to her device
|
||||
|
|
|
@ -25,7 +25,7 @@ func (m *Messenger) acceptContactRequest(requestID string, syncing bool) (*Messe
|
|||
m.logger.Info("acceptContactRequest")
|
||||
// We send a contact update for compatibility with 0.90 desktop, once that's
|
||||
// not an issue anymore, we can set the last bool flag to `false`
|
||||
return m.addContact(contactRequest.From, "", "", "", contactRequest.ID, syncing, true)
|
||||
return m.addContact(contactRequest.From, "", "", "", contactRequest.ID, "", syncing, true, false)
|
||||
}
|
||||
|
||||
func (m *Messenger) AcceptContactRequest(ctx context.Context, request *requests.AcceptContactRequest) (*MessengerResponse, error) {
|
||||
|
@ -47,6 +47,140 @@ func (m *Messenger) AcceptContactRequest(ctx context.Context, request *requests.
|
|||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) declineContactRequest(requestID string, syncing bool) (*MessengerResponse, error) {
|
||||
m.logger.Info("declineContactRequest")
|
||||
contactRequest, err := m.persistence.MessageByID(requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contact, err := m.BuildContact(contactRequest.From)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response := &MessengerResponse{}
|
||||
|
||||
if !syncing {
|
||||
_, clock, err := m.getOneToOneAndNextClock(contact)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contact.DismissContactRequest(clock)
|
||||
err = m.persistence.SaveContact(contact, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response.AddContact(contact)
|
||||
}
|
||||
contactRequest.ContactRequestState = common.ContactRequestStateDismissed
|
||||
|
||||
err = m.persistence.SetContactRequestState(contactRequest.ID, contactRequest.ContactRequestState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// update notification with the correct status
|
||||
notification, err := m.persistence.GetActivityCenterNotificationByID(types.FromHex(contactRequest.ID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if notification != nil {
|
||||
notification.Message = contactRequest
|
||||
notification.Read = true
|
||||
notification.Dismissed = true
|
||||
|
||||
err = m.addActivityCenterNotification(response, notification)
|
||||
if err != nil {
|
||||
m.logger.Error("failed to save notification", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
response.AddMessage(contactRequest)
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) DeclineContactRequest(ctx context.Context, request *requests.DeclineContactRequest) (*MessengerResponse, error) {
|
||||
err := request.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := m.declineContactRequest(request.ID.String(), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = m.syncContactRequestDecision(ctx, request.ID.String(), false, m.dispatchMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) cancelOutgoingContactRequest(ctx context.Context, ID string) (*MessengerResponse, error) {
|
||||
response := &MessengerResponse{}
|
||||
|
||||
// remove contact
|
||||
err := m.removeContact(ctx, response, ID, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// remove notification
|
||||
notificationID := types.FromHex(defaultContactRequestID(ID))
|
||||
notification, err := m.persistence.GetActivityCenterNotificationByID(notificationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if notification != nil {
|
||||
err := m.persistence.DeleteActivityCenterNotification(notificationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// retract contact
|
||||
clock, _ := m.getLastClockWithRelatedChat()
|
||||
retractContactRequest := &protobuf.RetractContactRequest{
|
||||
Clock: clock,
|
||||
}
|
||||
encodedMessage, err := proto.Marshal(retractContactRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = m.dispatchMessage(context.Background(), common.RawMessage{
|
||||
LocalChatID: ID,
|
||||
Payload: encodedMessage,
|
||||
MessageType: protobuf.ApplicationMetadataMessage_RETRACT_CONTACT_REQUEST,
|
||||
ResendAutomatically: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) CancelOutgoingContactRequest(ctx context.Context, request *requests.CancelOutgoingContactRequest) (*MessengerResponse, error) {
|
||||
err := request.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := m.cancelOutgoingContactRequest(ctx, request.ID.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) SendContactRequest(ctx context.Context, request *requests.SendContactRequest) (*MessengerResponse, error) {
|
||||
err := request.Validate()
|
||||
if err != nil {
|
||||
|
@ -55,7 +189,17 @@ func (m *Messenger) SendContactRequest(ctx context.Context, request *requests.Se
|
|||
|
||||
chatID := request.ID.String()
|
||||
|
||||
response, err := m.addContact(chatID, "", "", "", "", false, false)
|
||||
response, err := m.addContact(
|
||||
chatID,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
request.Message,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -100,82 +244,6 @@ func (m *Messenger) SendContactRequest(ctx context.Context, request *requests.Se
|
|||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) dismissContactRequest(requestID string, syncing bool) (*MessengerResponse, error) {
|
||||
m.logger.Info("dismissContactRequest")
|
||||
contactRequest, err := m.persistence.MessageByID(requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contact, err := m.BuildContact(contactRequest.From)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response := &MessengerResponse{}
|
||||
|
||||
if !syncing {
|
||||
_, clock, err := m.getOneToOneAndNextClock(contact)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contact.DismissContactRequest(clock)
|
||||
err = m.persistence.SaveContact(contact, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response.AddContact(contact)
|
||||
}
|
||||
contactRequest.ContactRequestState = common.ContactRequestStateDismissed
|
||||
|
||||
err = m.persistence.SetContactRequestState(contactRequest.ID, contactRequest.ContactRequestState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
notification, err := m.persistence.GetActivityCenterNotificationByID(types.FromHex(contactRequest.ID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if notification != nil {
|
||||
notification.Message = contactRequest
|
||||
notification.Read = true
|
||||
notification.Dismissed = true
|
||||
|
||||
err = m.addActivityCenterNotification(response, notification)
|
||||
if err != nil {
|
||||
m.logger.Error("failed to save notification", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
response.AddMessage(contactRequest)
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) DismissContactRequest(ctx context.Context, request *requests.DismissContactRequest) (*MessengerResponse, error) {
|
||||
err := request.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := m.dismissContactRequest(request.ID.String(), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = m.syncContactRequestDecision(ctx, request.ID.String(), false, m.dispatchMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) updateAcceptedContactRequest(response *MessengerResponse, contactRequestID string) (*MessengerResponse, error) {
|
||||
contactRequest, err := m.persistence.MessageByID(contactRequestID)
|
||||
if err != nil {
|
||||
|
@ -244,7 +312,7 @@ func (m *Messenger) updateAcceptedContactRequest(response *MessengerResponse, co
|
|||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) addContact(pubKey, ensName, nickname, displayName, contactRequestID string, syncing bool, sendContactUpdate bool) (*MessengerResponse, error) {
|
||||
func (m *Messenger) addContact(pubKey, ensName, nickname, displayName, contactRequestID string, contactRequestText string, syncing bool, sendContactUpdate bool, createOutgoingContactRequestNotification bool) (*MessengerResponse, error) {
|
||||
contact, err := m.BuildContact(pubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -256,13 +324,11 @@ func (m *Messenger) addContact(pubKey, ensName, nickname, displayName, contactRe
|
|||
}
|
||||
|
||||
if ensName != "" {
|
||||
clock := m.getTimesource().GetCurrentTime()
|
||||
err := m.ensVerifier.ENSVerified(pubKey, ensName, clock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := m.addENSNameToContact(contact); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -276,7 +342,6 @@ func (m *Messenger) addContact(pubKey, ensName, nickname, displayName, contactRe
|
|||
}
|
||||
|
||||
contact.LastUpdatedLocally = clock
|
||||
|
||||
contact.ContactRequestSent(clock)
|
||||
|
||||
if !syncing {
|
||||
|
@ -332,11 +397,13 @@ func (m *Messenger) addContact(pubKey, ensName, nickname, displayName, contactRe
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Get ENS name of a current user
|
||||
ensName, err = m.settings.ENSName()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get display name of a current user
|
||||
displayName, err = m.settings.DisplayName()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -372,11 +439,13 @@ func (m *Messenger) addContact(pubKey, ensName, nickname, displayName, contactRe
|
|||
}
|
||||
}
|
||||
|
||||
// Sends a standalone ChatIdentity message
|
||||
err = m.handleStandaloneChatIdentity(chat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Add chat
|
||||
response.AddChat(profileChat)
|
||||
|
||||
_, err = m.transport.InitFilters([]string{profileChat.ID}, []*ecdsa.PublicKey{publicKey})
|
||||
|
@ -390,18 +459,88 @@ func (m *Messenger) addContact(pubKey, ensName, nickname, displayName, contactRe
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Add outgoing contact request notification
|
||||
if createOutgoingContactRequestNotification {
|
||||
clock, timestamp := chat.NextClockAndTimestamp(m.transport)
|
||||
contactRequest, err := m.generateContactRequest(clock, timestamp, contact, contactRequestText)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response.AddMessage(contactRequest)
|
||||
err = m.persistence.SaveMessages([]*common.Message{contactRequest})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
notification := m.generateOutgoingContactRequestNotification(contact, contactRequest)
|
||||
err = m.addActivityCenterNotification(response, notification)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Add contact
|
||||
response.AddContact(contact)
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) generateContactRequest(clock uint64, timestamp uint64, contact *Contact, text string) (*common.Message, error) {
|
||||
if contact == nil {
|
||||
return nil, errors.New("contact cannot be nil")
|
||||
}
|
||||
|
||||
contactRequest := &common.Message{}
|
||||
contactRequest.WhisperTimestamp = timestamp
|
||||
contactRequest.Seen = true
|
||||
contactRequest.Text = text
|
||||
contactRequest.From = contact.ID
|
||||
contactRequest.LocalChatID = contact.ID
|
||||
contactRequest.ContentType = protobuf.ChatMessage_CONTACT_REQUEST
|
||||
contactRequest.Clock = clock
|
||||
contactRequest.ID = defaultContactRequestID(contact.ID)
|
||||
if contact.mutual() {
|
||||
contactRequest.ContactRequestState = common.ContactRequestStateAccepted
|
||||
} else {
|
||||
contactRequest.ContactRequestState = common.ContactRequestStatePending
|
||||
}
|
||||
err := contactRequest.PrepareContent(common.PubkeyToHex(&m.identity.PublicKey))
|
||||
return contactRequest, err
|
||||
}
|
||||
|
||||
func (m *Messenger) generateOutgoingContactRequestNotification(contact *Contact, contactRequest *common.Message) *ActivityCenterNotification {
|
||||
return &ActivityCenterNotification{
|
||||
ID: types.FromHex(contactRequest.ID),
|
||||
Type: ActivityCenterNotificationTypeContactRequest,
|
||||
Name: contact.CanonicalName(),
|
||||
Author: m.myHexIdentity(),
|
||||
Message: contactRequest,
|
||||
Timestamp: m.getTimesource().GetCurrentTime(),
|
||||
ChatID: contact.ID,
|
||||
Read: contactRequest.ContactRequestState == common.ContactRequestStateAccepted || contactRequest.ContactRequestState == common.ContactRequestStateDismissed,
|
||||
Accepted: contactRequest.ContactRequestState == common.ContactRequestStateAccepted,
|
||||
Dismissed: contactRequest.ContactRequestState == common.ContactRequestStateDismissed,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Messenger) AddContact(ctx context.Context, request *requests.AddContact) (*MessengerResponse, error) {
|
||||
err := request.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m.addContact(request.ID.String(), request.ENSName, request.Nickname, request.DisplayName, "", false, true)
|
||||
return m.addContact(
|
||||
request.ID.String(),
|
||||
request.ENSName,
|
||||
request.Nickname,
|
||||
request.DisplayName,
|
||||
"",
|
||||
"Please add me to your contacts",
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (m *Messenger) resetLastPublishedTimeForChatIdentity() error {
|
||||
|
@ -801,7 +940,7 @@ func (m *Messenger) RetractContactRequest(request *requests.RetractContactReques
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
contact, ok := m.allContacts.Load(request.ContactID.String())
|
||||
contact, ok := m.allContacts.Load(request.ID.String())
|
||||
if !ok {
|
||||
return nil, errors.New("contact not found")
|
||||
}
|
||||
|
@ -874,7 +1013,7 @@ func (m *Messenger) DismissLatestContactRequestForContact(ctx context.Context, r
|
|||
contactRequestID = defaultContactRequestID(request.ID.String())
|
||||
}
|
||||
|
||||
return m.DismissContactRequest(ctx, &requests.DismissContactRequest{ID: types.Hex2Bytes(contactRequestID)})
|
||||
return m.DeclineContactRequest(ctx, &requests.DeclineContactRequest{ID: types.Hex2Bytes(contactRequestID)})
|
||||
}
|
||||
|
||||
func (m *Messenger) PendingContactRequests(cursor string, limit int) ([]*common.Message, string, error) {
|
||||
|
|
|
@ -262,7 +262,28 @@ func (m *Messenger) PendingNotificationContactRequest(contactID string) (*Activi
|
|||
return m.persistence.ActiveContactRequestNotification(contactID)
|
||||
}
|
||||
|
||||
func (m *Messenger) createContactRequestNotification(contact *Contact, messageState *ReceivedMessageState, contactRequest *common.Message, createNewNotification bool) error {
|
||||
func (m *Messenger) createIncomingContactRequestNotification(contact *Contact, messageState *ReceivedMessageState, contactRequest *common.Message, createNewNotification bool) error {
|
||||
if contactRequest != nil && contactRequest.ContactRequestState == common.ContactRequestStateAccepted {
|
||||
// Pull one from the db if there
|
||||
notification, err := m.persistence.GetActivityCenterNotificationByID(types.FromHex(contactRequest.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if notification != nil {
|
||||
notification.Message = contactRequest
|
||||
notification.Read = true
|
||||
notification.Accepted = true
|
||||
notification.Dismissed = false
|
||||
err = m.persistence.SaveActivityCenterNotification(notification)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
messageState.Response.AddMessage(contactRequest)
|
||||
messageState.Response.AddActivityCenterNotification(notification)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if contactRequest == nil || contactRequest.ContactRequestState == common.ContactRequestStatePending {
|
||||
notification, err := m.PendingNotificationContactRequest(contact.ID)
|
||||
|
@ -321,28 +342,19 @@ func (m *Messenger) createContactRequestNotification(contact *Contact, messageSt
|
|||
}
|
||||
}
|
||||
|
||||
contactRequest = &common.Message{}
|
||||
|
||||
contactRequest.WhisperTimestamp = messageState.CurrentMessageState.WhisperTimestamp
|
||||
contactRequest.Seen = true
|
||||
contactRequest.Text = "Please add me to your contacts"
|
||||
contactRequest.From = contact.ID
|
||||
contactRequest.ContentType = protobuf.ChatMessage_CONTACT_REQUEST
|
||||
contactRequest.Clock = messageState.CurrentMessageState.Message.Clock
|
||||
contactRequest.ID = defaultID
|
||||
|
||||
if contact.mutual() {
|
||||
contactRequest.ContactRequestState = common.ContactRequestStateAccepted
|
||||
} else {
|
||||
contactRequest.ContactRequestState = common.ContactRequestStatePending
|
||||
}
|
||||
err = contactRequest.PrepareContent(common.PubkeyToHex(&m.identity.PublicKey))
|
||||
// generate request message
|
||||
contactRequest, err = m.generateContactRequest(
|
||||
messageState.CurrentMessageState.Message.Clock,
|
||||
messageState.CurrentMessageState.WhisperTimestamp,
|
||||
contact,
|
||||
"Please add me to your contacts",
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// save this message
|
||||
messageState.Response.AddMessage(contactRequest)
|
||||
|
||||
err = m.persistence.SaveMessages([]*common.Message{contactRequest})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -762,10 +774,10 @@ func (m *Messenger) handleAcceptContactRequest(
|
|||
response *MessengerResponse,
|
||||
contact *Contact,
|
||||
originalRequest *common.Message,
|
||||
message protobuf.AcceptContactRequest) (ContactRequestProcessingResponse, error) {
|
||||
clock uint64) (ContactRequestProcessingResponse, error) {
|
||||
|
||||
m.logger.Debug("received contact request", zap.Uint64("clock-sent", message.Clock), zap.Uint64("current-clock", contact.ContactRequestRemoteClock), zap.Uint64("current-state", uint64(contact.ContactRequestRemoteState)))
|
||||
if contact.ContactRequestRemoteClock > message.Clock {
|
||||
m.logger.Debug("received contact request", zap.Uint64("clock-sent", clock), zap.Uint64("current-clock", contact.ContactRequestRemoteClock), zap.Uint64("current-state", uint64(contact.ContactRequestRemoteState)))
|
||||
if contact.ContactRequestRemoteClock > clock {
|
||||
m.logger.Debug("not handling accept since clock lower")
|
||||
return ContactRequestProcessingResponse{}, nil
|
||||
}
|
||||
|
@ -774,14 +786,14 @@ func (m *Messenger) handleAcceptContactRequest(
|
|||
// be that we sent a legacy contact request/contact-update, or another
|
||||
// device has sent it, and we haven't synchronized it
|
||||
if originalRequest == nil {
|
||||
return contact.ContactRequestAccepted(message.Clock), nil
|
||||
return contact.ContactRequestAccepted(clock), nil
|
||||
}
|
||||
|
||||
if originalRequest.LocalChatID != contact.ID {
|
||||
return ContactRequestProcessingResponse{}, errors.New("can't accept contact request not sent to user")
|
||||
}
|
||||
|
||||
contact.ContactRequestAccepted(message.Clock)
|
||||
contact.ContactRequestAccepted(clock)
|
||||
|
||||
originalRequest.ContactRequestState = common.ContactRequestStateAccepted
|
||||
|
||||
|
@ -794,15 +806,15 @@ func (m *Messenger) handleAcceptContactRequest(
|
|||
return ContactRequestProcessingResponse{}, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) HandleAcceptContactRequest(state *ReceivedMessageState, message protobuf.AcceptContactRequest) error {
|
||||
originalRequest, err := m.persistence.MessageByID(message.Id)
|
||||
func (m *Messenger) handleAcceptContactRequestMessage(state *ReceivedMessageState, clock uint64, contactRequestID string, isOutgoing bool) error {
|
||||
request, err := m.persistence.MessageByID(contactRequestID)
|
||||
if err != nil && err != common.ErrRecordNotFound {
|
||||
return err
|
||||
}
|
||||
|
||||
contact := state.CurrentMessageState.Contact
|
||||
|
||||
processingResponse, err := m.handleAcceptContactRequest(state.Response, contact, originalRequest, message)
|
||||
processingResponse, err := m.handleAcceptContactRequest(state.Response, contact, request, clock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -818,14 +830,14 @@ func (m *Messenger) HandleAcceptContactRequest(state *ReceivedMessageState, mess
|
|||
return err
|
||||
}
|
||||
|
||||
if chat.LastClockValue < message.Clock {
|
||||
chat.LastClockValue = message.Clock
|
||||
if chat.LastClockValue < clock {
|
||||
chat.LastClockValue = clock
|
||||
}
|
||||
|
||||
// NOTE(cammellos): This will re-enable the chat if it was deleted, and only
|
||||
// after we became contact, currently seems safe, but that needs
|
||||
// discussing with UX.
|
||||
if chat.DeletedAtClockValue < message.Clock {
|
||||
if chat.DeletedAtClockValue < clock {
|
||||
chat.Active = true
|
||||
}
|
||||
|
||||
|
@ -833,9 +845,16 @@ func (m *Messenger) HandleAcceptContactRequest(state *ReceivedMessageState, mess
|
|||
state.AllChats.Store(chat.ID, chat)
|
||||
}
|
||||
|
||||
if originalRequest != nil {
|
||||
// Update contact requests if existing, or create a new one
|
||||
err = m.createContactRequestNotification(contact, state, originalRequest, processingResponse.newContactRequestReceived)
|
||||
if request != nil {
|
||||
if isOutgoing {
|
||||
notification := m.generateOutgoingContactRequestNotification(contact, request)
|
||||
err = m.addActivityCenterNotification(state.Response, notification)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err = m.createIncomingContactRequestNotification(contact, state, request, processingResponse.newContactRequestReceived)
|
||||
}
|
||||
if err != nil {
|
||||
m.logger.Warn("could not create contact request notification", zap.Error(err))
|
||||
}
|
||||
|
@ -846,6 +865,22 @@ func (m *Messenger) HandleAcceptContactRequest(state *ReceivedMessageState, mess
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Messenger) HandleAcceptContactRequest(state *ReceivedMessageState, message protobuf.AcceptContactRequest, senderID string) error {
|
||||
// outgoing contact requests are created on the side of a sender
|
||||
err := m.handleAcceptContactRequestMessage(state, message.Clock, defaultContactRequestID(senderID), true)
|
||||
if err != nil {
|
||||
m.logger.Warn("could not accept contact request", zap.Error(err))
|
||||
}
|
||||
|
||||
// legacy contact requests: the ones that are send with SendContactRequest
|
||||
err = m.handleAcceptContactRequestMessage(state, message.Clock, message.Id, false)
|
||||
if err != nil {
|
||||
m.logger.Warn("could not accept contact request", zap.Error(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Messenger) handleRetractContactRequest(contact *Contact, message protobuf.RetractContactRequest) error {
|
||||
if contact.ID == m.myHexIdentity() {
|
||||
m.logger.Debug("retraction coming from us, ignoring")
|
||||
|
@ -922,7 +957,7 @@ func (m *Messenger) HandleContactUpdate(state *ReceivedMessageState, message pro
|
|||
|
||||
}
|
||||
if result.newContactRequestReceived {
|
||||
err = m.createContactRequestNotification(contact, state, nil, true)
|
||||
err = m.createIncomingContactRequestNotification(contact, state, nil, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -946,7 +981,7 @@ func (m *Messenger) HandleContactUpdate(state *ReceivedMessageState, message pro
|
|||
|
||||
r := contact.ContactRequestReceived(message.ContactRequestClock)
|
||||
if r.newContactRequestReceived {
|
||||
err = m.createContactRequestNotification(contact, state, nil, true)
|
||||
err = m.createIncomingContactRequestNotification(contact, state, nil, true)
|
||||
if err != nil {
|
||||
m.logger.Warn("could not create contact request notification", zap.Error(err))
|
||||
}
|
||||
|
@ -1255,7 +1290,7 @@ func (m *Messenger) HandleCommunityRequestToJoin(state *ReceivedMessageState, si
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
// Activity Center notification, updating existing for accespted/declined
|
||||
// Activity Center notification, updating existing for accepted/declined
|
||||
notification, err := m.persistence.GetActivityCenterNotificationByID(requestToJoin.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -1751,7 +1786,7 @@ func (m *Messenger) HandleChatMessage(state *ReceivedMessageState) error {
|
|||
receivedMessage.ContactRequestState = common.ContactRequestStatePending
|
||||
}
|
||||
|
||||
err = m.createContactRequestNotification(contact, state, receivedMessage, true)
|
||||
err = m.createIncomingContactRequestNotification(contact, state, receivedMessage, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1762,7 +1797,6 @@ func (m *Messenger) HandleChatMessage(state *ReceivedMessageState) error {
|
|||
}
|
||||
|
||||
if receivedMessage.ContentType == protobuf.ChatMessage_CONTACT_REQUEST && chat.OneToOne() {
|
||||
|
||||
chatContact := contact
|
||||
if isSyncMessage {
|
||||
chatContact, err = m.BuildContact(chat.ID)
|
||||
|
@ -1780,7 +1814,7 @@ func (m *Messenger) HandleChatMessage(state *ReceivedMessageState) error {
|
|||
state.AllContacts.Store(chatContact.ID, chatContact)
|
||||
|
||||
if sendNotification {
|
||||
err = m.createContactRequestNotification(chatContact, state, receivedMessage, true)
|
||||
err = m.createIncomingContactRequestNotification(chatContact, state, receivedMessage, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -2668,13 +2702,12 @@ func (m *Messenger) HandleSyncWalletAccount(state *ReceivedMessageState, message
|
|||
func (m *Messenger) HandleSyncContactRequestDecision(state *ReceivedMessageState, message protobuf.SyncContactRequestDecision) error {
|
||||
var err error
|
||||
var response *MessengerResponse
|
||||
|
||||
if message.DecisionStatus == protobuf.SyncContactRequestDecision_ACCEPTED {
|
||||
response, err = m.updateAcceptedContactRequest(nil, message.RequestId)
|
||||
|
||||
} else {
|
||||
response, err = m.dismissContactRequest(message.RequestId, true)
|
||||
response, err = m.declineContactRequest(message.RequestId, true)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
var ErrCancelOutgoingContactRequestInvalidID = errors.New("cancel-outgoing-contact-request: invalid id")
|
||||
|
||||
type CancelOutgoingContactRequest struct {
|
||||
ID types.HexBytes `json:"id"`
|
||||
}
|
||||
|
||||
func (a *CancelOutgoingContactRequest) Validate() error {
|
||||
if len(a.ID) == 0 {
|
||||
return ErrCancelOutgoingContactRequestInvalidID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
var ErrDeclineContactRequestInvalidID = errors.New("decline-contact-request: invalid id")
|
||||
|
||||
type DeclineContactRequest struct {
|
||||
ID types.HexBytes `json:"id"`
|
||||
}
|
||||
|
||||
func (a *DeclineContactRequest) Validate() error {
|
||||
if len(a.ID) == 0 {
|
||||
return ErrDeclineContactRequestInvalidID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
var ErrDismissContactRequestInvalidID = errors.New("dismiss-contact-request: invalid id")
|
||||
|
||||
type DismissContactRequest struct {
|
||||
ID types.HexBytes `json:"id"`
|
||||
}
|
||||
|
||||
func (a *DismissContactRequest) Validate() error {
|
||||
if len(a.ID) == 0 {
|
||||
return ErrDismissContactRequestInvalidID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -9,11 +9,11 @@ import (
|
|||
var ErrRetractContactRequestInvalidContactID = errors.New("retract-contact-request: invalid id")
|
||||
|
||||
type RetractContactRequest struct {
|
||||
ContactID types.HexBytes `json:"contactId"`
|
||||
ID types.HexBytes `json:"id"`
|
||||
}
|
||||
|
||||
func (a *RetractContactRequest) Validate() error {
|
||||
if len(a.ContactID) == 0 {
|
||||
if len(a.ID) == 0 {
|
||||
return ErrRetractContactRequestInvalidContactID
|
||||
}
|
||||
|
||||
|
|
|
@ -695,18 +695,26 @@ func (api *PublicAPI) MarkAllReadInCommunity(communityID string) ([]string, erro
|
|||
return api.service.messenger.MarkAllReadInCommunity(communityID)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) AddContact(ctx context.Context, request *requests.AddContact) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.AddContact(ctx, request)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) SendContactRequest(ctx context.Context, request *requests.SendContactRequest) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.SendContactRequest(ctx, request)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) AddContact(ctx context.Context, request *requests.AddContact) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.AddContact(ctx, request)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) AcceptContactRequest(ctx context.Context, request *requests.AcceptContactRequest) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.AcceptContactRequest(ctx, request)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) DeclineContactRequest(ctx context.Context, request *requests.DeclineContactRequest) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.DeclineContactRequest(ctx, request)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) CancelOutgoingContactRequest(ctx context.Context, request *requests.CancelOutgoingContactRequest) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.CancelOutgoingContactRequest(ctx, request)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) AcceptLatestContactRequestForContact(ctx context.Context, request *requests.AcceptLatestContactRequestForContact) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.AcceptLatestContactRequestForContact(ctx, request)
|
||||
}
|
||||
|
@ -719,10 +727,6 @@ func (api *PublicAPI) RetractContactRequest(ctx context.Context, request *reques
|
|||
return api.service.messenger.RetractContactRequest(request)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) DismissContactRequest(ctx context.Context, request *requests.DismissContactRequest) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.DismissContactRequest(ctx, request)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) RemoveContact(ctx context.Context, pubKey string) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.RemoveContact(ctx, pubKey)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue