diff --git a/protocol/activity_center_persistence.go b/protocol/activity_center_persistence.go index ec32d6fc3..ced7c997b 100644 --- a/protocol/activity_center_persistence.go +++ b/protocol/activity_center_persistence.go @@ -9,7 +9,6 @@ import ( "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/protocol/common" - "github.com/status-im/status-go/protocol/verification" ) func (db sqlitePersistence) DeleteActivityCenterNotification(id []byte) error { @@ -121,7 +120,21 @@ 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, contact_verification_status) VALUES (?,?,?,?,?,?,?,?,?,?)`, notification.ID, notification.Timestamp, notification.Type, notification.ChatID, notification.CommunityID, notification.MembershipStatus, encodedMessage, encodedReplyMessage, notification.Author, notification.ContactVerificationStatus) + _, 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, read, accepted, dismissed) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)`, + notification.ID, + notification.Timestamp, + notification.Type, + notification.ChatID, + notification.CommunityID, + notification.MembershipStatus, + encodedMessage, + encodedReplyMessage, + notification.Author, + notification.ContactVerificationStatus, + notification.Read, + notification.Accepted, + notification.Dismissed, + ) return err } @@ -305,8 +318,7 @@ type activityCenterQueryParams struct { func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activityCenterQueryParams) (string, []*ActivityCenterNotification, error) { var args []interface{} - - var cursorWhere, inQueryWhere, inChatWhere, fromAuthorWhere, inTypeWhere, readWhere, acceptedWhere string + var conditions []string cursor := params.cursor ids := params.ids @@ -318,13 +330,13 @@ func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activity accepted := params.accepted if cursor != "" { - cursorWhere = "AND cursor <= ?" //nolint: goconst + conditions = append(conditions, "cursor <= ?") args = append(args, cursor) } if len(ids) != 0 { inVector := strings.Repeat("?, ", len(ids)-1) + "?" - inQueryWhere = fmt.Sprintf(" AND a.id IN (%s)", inVector) + conditions = append(conditions, fmt.Sprintf("a.id IN (%s)", inVector)) for _, id := range ids { args = append(args, id) } @@ -332,33 +344,38 @@ func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activity switch read { case ActivityCenterQueryParamsReadRead: - readWhere = "AND a.read = 1" + conditions = append(conditions, "a.read = 1") case ActivityCenterQueryParamsReadUnread: - readWhere = "AND NOT(a.read)" + conditions = append(conditions, "NOT a.read") } if !accepted { - acceptedWhere = "AND NOT a.accepted" + conditions = append(conditions, "NOT a.accepted") } if chatID != "" { - inChatWhere = "AND a.chat_id = ?" //nolint: goconst + conditions = append(conditions, "a.chat_id = ?") args = append(args, chatID) } if author != "" { - fromAuthorWhere = " AND a.author = ?" + conditions = append(conditions, "a.author = ?") args = append(args, author) } - if len(activityCenterTypes) != 0 { + if len(activityCenterTypes) > 0 { inVector := strings.Repeat("?, ", len(activityCenterTypes)-1) + "?" - inTypeWhere = fmt.Sprintf(" AND a.notification_type IN (%s)", inVector) + conditions = append(conditions, fmt.Sprintf("a.notification_type IN (%s)", inVector)) for _, activityCenterType := range activityCenterTypes { args = append(args, activityCenterType) } } + var conditionsString string + if len(conditions) > 0 { + conditionsString = " WHERE " + strings.Join(conditions, " AND ") + } + query := fmt.Sprintf( // nolint: gosec ` SELECT @@ -382,15 +399,8 @@ func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activity LEFT JOIN chats c ON c.id = a.chat_id - WHERE NOT a.dismissed %s - %s - %s - %s - %s - %s - %s - ORDER BY cursor DESC`, cursorWhere, inQueryWhere, inChatWhere, fromAuthorWhere, inTypeWhere, readWhere, acceptedWhere) + ORDER BY cursor DESC`, conditionsString) if limit != 0 { args = append(args, limit) @@ -401,6 +411,7 @@ func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activity if err != nil { return "", nil, err } + return db.unmarshalActivityCenterNotificationRows(rows) } @@ -713,39 +724,6 @@ func (db sqlitePersistence) AcceptActivityCenterNotifications(ids []types.HexByt return notifications, err } -func (db sqlitePersistence) UpdateActivityCenterNotificationMessage(id types.HexBytes, message *common.Message) error { - encodedMessage, err := json.Marshal(message) - if err != nil { - return err - } - - _, err = db.db.Exec(`UPDATE activity_center_notifications SET message = ? WHERE id = ?`, encodedMessage, id) - return err - -} - -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 - -} - -func (db sqlitePersistence) UpdateActivityCenterNotificationFields(id types.HexBytes, message *common.Message, replyMessage *common.Message, status verification.RequestStatus) error { - encodedMessage, err := json.Marshal(message) - if err != nil { - return err - } - - encodedReplyMessage, err := json.Marshal(replyMessage) - if err != nil { - return err - } - - _, err = db.db.Exec(`UPDATE activity_center_notifications SET message = ?, reply_message = ?, contact_verification_status = ? WHERE id = ?`, encodedMessage, encodedReplyMessage, status, id) - return err - -} - func (db sqlitePersistence) AcceptActivityCenterNotificationsForInvitesFromUser(userPublicKey string) ([]*ActivityCenterNotification, error) { var tx *sql.Tx var err error diff --git a/protocol/communities_messenger_test.go b/protocol/communities_messenger_test.go index 258e7cc4d..cc80cc128 100644 --- a/protocol/communities_messenger_test.go +++ b/protocol/communities_messenger_test.go @@ -928,6 +928,9 @@ func (s *MessengerCommunitiesSuite) TestRequestAccess() { s.Require().NotNil(notification) s.Require().Equal(notification.Type, ActivityCenterNotificationTypeCommunityRequest) s.Require().Equal(notification.MembershipStatus, ActivityCenterMembershipStatusPending) + s.Require().Equal(notification.Read, true) + s.Require().Equal(notification.Accepted, false) + s.Require().Equal(notification.Dismissed, false) requestToJoin1 := response.RequestsToJoinCommunity[0] s.Require().NotNil(requestToJoin1) @@ -1013,6 +1016,9 @@ func (s *MessengerCommunitiesSuite) TestRequestAccess() { s.Require().NotNil(notification) s.Require().Equal(notification.Type, ActivityCenterNotificationTypeCommunityMembershipRequest) s.Require().Equal(notification.MembershipStatus, ActivityCenterMembershipStatusAccepted) + s.Require().Equal(notification.Read, true) + s.Require().Equal(notification.Accepted, true) + s.Require().Equal(notification.Dismissed, false) // Pull message and make sure org is received err = tt.RetryWithBackOff(func() error { @@ -1266,6 +1272,9 @@ func (s *MessengerCommunitiesSuite) TestRequestAccessAgain() { s.Require().NotNil(notification) s.Require().Equal(notification.Type, ActivityCenterNotificationTypeCommunityRequest) s.Require().Equal(notification.MembershipStatus, ActivityCenterMembershipStatusPending) + s.Require().Equal(notification.Read, true) + s.Require().Equal(notification.Accepted, false) + s.Require().Equal(notification.Dismissed, false) requestToJoin1 := response.RequestsToJoinCommunity[0] s.Require().NotNil(requestToJoin1) @@ -1350,6 +1359,9 @@ func (s *MessengerCommunitiesSuite) TestRequestAccessAgain() { s.Require().NotNil(notification) s.Require().Equal(notification.Type, ActivityCenterNotificationTypeCommunityMembershipRequest) s.Require().Equal(notification.MembershipStatus, ActivityCenterMembershipStatusAccepted) + s.Require().Equal(notification.Read, true) + s.Require().Equal(notification.Accepted, true) + s.Require().Equal(notification.Dismissed, false) s.Require().Len(response.Communities(), 1) @@ -1551,6 +1563,9 @@ func (s *MessengerCommunitiesSuite) TestDeclineAccess() { s.Require().NotNil(notification) s.Require().Equal(notification.Type, ActivityCenterNotificationTypeCommunityRequest) s.Require().Equal(notification.MembershipStatus, ActivityCenterMembershipStatusPending) + s.Require().Equal(notification.Read, true) + s.Require().Equal(notification.Dismissed, false) + s.Require().Equal(notification.Accepted, false) // Make sure clock is not empty s.Require().NotEmpty(requestToJoin1.Clock) @@ -1617,6 +1632,9 @@ func (s *MessengerCommunitiesSuite) TestDeclineAccess() { s.Require().NotNil(notification) s.Require().Equal(notification.Type, ActivityCenterNotificationTypeCommunityMembershipRequest) s.Require().Equal(notification.MembershipStatus, ActivityCenterMembershipStatusDeclined) + s.Require().Equal(notification.Read, true) + s.Require().Equal(notification.Accepted, false) + s.Require().Equal(notification.Dismissed, true) // Check if admin sees requests correctly requestsToJoin, err = s.bob.PendingRequestsToJoinForCommunity(community.ID()) diff --git a/protocol/messenger.go b/protocol/messenger.go index 0fb0214f8..6bf3b51cd 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -3074,7 +3074,7 @@ func (r *ReceivedMessageState) addNewActivityCenterNotification(publicKey ecdsa. err := m.persistence.SaveActivityCenterNotification(notification) if err != nil { - m.logger.Warn("failed to save notification", zap.Error(err)) + m.logger.Error("failed to save notification", zap.Error(err)) return err } r.Response.AddActivityCenterNotification(notification) diff --git a/protocol/messenger_activity_center.go b/protocol/messenger_activity_center.go index cd2eedf73..762150d35 100644 --- a/protocol/messenger_activity_center.go +++ b/protocol/messenger_activity_center.go @@ -235,6 +235,10 @@ func (m *Messenger) DismissActivityCenterNotifications(ctx context.Context, ids return nil, err } +func (m *Messenger) ActivityCenterNotification(id types.HexBytes) (*ActivityCenterNotification, error) { + return m.persistence.GetActivityCenterNotificationByID(id) +} + func (m *Messenger) ActivityCenterNotifications(cursor string, limit uint64) (*ActivityCenterPaginationResponse, error) { cursor, notifications, err := m.persistence.ActivityCenterNotifications(cursor, limit) if err != nil { diff --git a/protocol/messenger_communities.go b/protocol/messenger_communities.go index 78f679d92..a79c80fa6 100644 --- a/protocol/messenger_communities.go +++ b/protocol/messenger_communities.go @@ -552,12 +552,13 @@ func (m *Messenger) RequestToJoinCommunity(request *requests.RequestToJoinCommun Timestamp: m.getTimesource().GetCurrentTime(), CommunityID: community.IDString(), MembershipStatus: ActivityCenterMembershipStatusPending, + Read: true, } - saveErr := m.persistence.SaveActivityCenterNotification(notification) - if saveErr != nil { - m.logger.Warn("failed to save notification", zap.Error(saveErr)) - return nil, saveErr + err = m.persistence.SaveActivityCenterNotification(notification) + if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) + return nil, err } response.AddActivityCenterNotification(notification) @@ -763,10 +764,13 @@ func (m *Messenger) AcceptRequestToJoinCommunity(request *requests.AcceptRequest if notification != nil { notification.MembershipStatus = ActivityCenterMembershipStatusAccepted - saveErr := m.persistence.SaveActivityCenterNotification(notification) - if saveErr != nil { - m.logger.Warn("failed to save notification", zap.Error(saveErr)) - return nil, saveErr + notification.Read = true + notification.Accepted = true + + err = m.persistence.SaveActivityCenterNotification(notification) + if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) + return nil, err } response.AddActivityCenterNotification(notification) } @@ -794,10 +798,13 @@ func (m *Messenger) DeclineRequestToJoinCommunity(request *requests.DeclineReque if notification != nil { notification.MembershipStatus = ActivityCenterMembershipStatusDeclined - saveErr := m.persistence.SaveActivityCenterNotification(notification) - if saveErr != nil { - m.logger.Warn("failed to save notification", zap.Error(saveErr)) - return nil, saveErr + notification.Read = true + notification.Dismissed = true + + err = m.persistence.SaveActivityCenterNotification(notification) + if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) + return nil, err } response.AddActivityCenterNotification(notification) } diff --git a/protocol/messenger_contact_requests_test.go b/protocol/messenger_contact_requests_test.go index 97cb5247c..9f95993a0 100644 --- a/protocol/messenger_contact_requests_test.go +++ b/protocol/messenger_contact_requests_test.go @@ -110,6 +110,9 @@ func (s *MessengerContactRequestSuite) TestReceiveAndAcceptContactRequest() { s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) s.Require().Equal(common.ContactRequestStatePending, resp.ActivityCenterNotifications()[0].Message.ContactRequestState) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) // Check the contact state is correctly set s.Require().Len(resp.Contacts, 1) @@ -162,6 +165,9 @@ func (s *MessengerContactRequestSuite) TestReceiveAndAcceptContactRequest() { s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) // Make sure the message is updated, sender s2de s.Require().NotNil(resp) @@ -227,6 +233,9 @@ func (s *MessengerContactRequestSuite) TestReceiveAndDismissContactRequest() { s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) s.Require().Equal(common.ContactRequestStatePending, resp.ActivityCenterNotifications()[0].Message.ContactRequestState) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) // Check the contact state is correctly set s.Require().Len(resp.Contacts, 1) @@ -258,6 +267,9 @@ func (s *MessengerContactRequestSuite) TestReceiveAndDismissContactRequest() { s.Require().Len(resp.ActivityCenterNotifications(), 1) s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), contactRequests[0].ID) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, true) s.Require().Equal(common.ContactRequestStateDismissed, resp.ActivityCenterNotifications()[0].Message.ContactRequestState) // Make sure the sender is not added to our contacts @@ -974,7 +986,7 @@ func (s *MessengerContactRequestSuite) TestLegacyContactRequestNotifications() { paginationResponse, err = theirMessenger.ActivityCenterNotifications("", 10) s.Require().NoError(err) - s.Require().Len(paginationResponse.Notifications, 1) + s.Require().Len(paginationResponse.Notifications, 2) } func (s *MessengerContactRequestSuite) TestReceiveMultipleLegacy() { diff --git a/protocol/messenger_contact_verification.go b/protocol/messenger_contact_verification.go index c08e3142d..b39eb00d1 100644 --- a/protocol/messenger_contact_verification.go +++ b/protocol/messenger_contact_verification.go @@ -242,16 +242,14 @@ func (m *Messenger) CancelVerificationRequest(ctx context.Context, id string) (* } if notification != nil { - err := m.persistence.UpdateActivityCenterNotificationContactVerificationStatus(notification.ID, verification.RequestStatusCANCELED) - if err != nil { - return nil, err - } - notification.ContactVerificationStatus = verification.RequestStatusCANCELED message := notification.Message message.ContactVerificationState = common.ContactVerificationStateCanceled - err = m.persistence.UpdateActivityCenterNotificationMessage(notification.ID, message) + notification.Read = true + + err = m.persistence.SaveActivityCenterNotification(notification) if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) return nil, err } response.AddActivityCenterNotification(notification) @@ -357,9 +355,12 @@ func (m *Messenger) AcceptContactVerificationRequest(ctx context.Context, id str message := notification.Message message.ContactVerificationState = common.ContactVerificationStateAccepted notification.ReplyMessage = replyMessage + notification.Read = true + notification.Accepted = true - err := m.persistence.UpdateActivityCenterNotificationFields(notification.ID, message, replyMessage, verification.RequestStatusACCEPTED) + err = m.persistence.SaveActivityCenterNotification(notification) if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) return nil, err } @@ -451,9 +452,12 @@ func (m *Messenger) VerifiedTrusted(ctx context.Context, request *requests.Verif notification.ContactVerificationStatus = verification.RequestStatusTRUSTED notification.Message.ContactVerificationState = common.ContactVerificationStateTrusted + notification.Read = true + notification.Accepted = true - err = m.persistence.UpdateActivityCenterNotificationFields(notification.ID, notification.Message, notification.ReplyMessage, notification.ContactVerificationStatus) + err = m.persistence.SaveActivityCenterNotification(notification) if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) return nil, err } @@ -556,9 +560,12 @@ func (m *Messenger) VerifiedUntrustworthy(ctx context.Context, request *requests notification.ContactVerificationStatus = verification.RequestStatusUNTRUSTWORTHY notification.Message.ContactVerificationState = common.ContactVerificationStateUntrustworthy + notification.Read = true + notification.Accepted = true - err = m.persistence.UpdateActivityCenterNotificationFields(notification.ID, notification.Message, notification.ReplyMessage, notification.ContactVerificationStatus) + err = m.persistence.SaveActivityCenterNotification(notification) if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) return nil, err } @@ -661,19 +668,19 @@ func (m *Messenger) DeclineContactVerificationRequest(ctx context.Context, id st } if notification != nil { - // TODO: Should we update only the message or only the notification or both? - err := m.persistence.UpdateActivityCenterNotificationContactVerificationStatus(notification.ID, verification.RequestStatusDECLINED) + notification.ContactVerificationStatus = verification.RequestStatusDECLINED + notification.Read = true + notification.Dismissed = true + + message := notification.Message + message.ContactVerificationState = common.ContactVerificationStateDeclined + + err = m.persistence.SaveActivityCenterNotification(notification) if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) 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) } @@ -1040,6 +1047,9 @@ func (m *Messenger) createOrUpdateOutgoingContactVerificationNotification(contac Timestamp: chatMessage.WhisperTimestamp, ChatID: contact.ID, ContactVerificationStatus: vr.RequestStatus, + Read: vr.RequestStatus != verification.RequestStatusACCEPTED, // Mark as Unread Accepted notification because we are waiting for the asnwer + Accepted: vr.RequestStatus == verification.RequestStatusTRUSTED || vr.RequestStatus == verification.RequestStatusUNTRUSTWORTHY, + Dismissed: vr.RequestStatus == verification.RequestStatusDECLINED, } return m.addActivityCenterNotification(response, notification) @@ -1056,6 +1066,9 @@ func (m *Messenger) createOrUpdateIncomingContactVerificationNotification(contac Timestamp: messageState.CurrentMessageState.WhisperTimestamp, ChatID: contact.ID, ContactVerificationStatus: vr.RequestStatus, + Read: vr.RequestStatus != verification.RequestStatusPENDING, // Unread only for pending incomming + Accepted: vr.RequestStatus == verification.RequestStatusACCEPTED || vr.RequestStatus == verification.RequestStatusTRUSTED || vr.RequestStatus == verification.RequestStatusUNTRUSTWORTHY, + Dismissed: vr.RequestStatus == verification.RequestStatusDECLINED, } return m.addActivityCenterNotification(messageState.Response, notification) diff --git a/protocol/messenger_contact_verification_test.go b/protocol/messenger_contact_verification_test.go index 68da2d9d6..7caa2467d 100644 --- a/protocol/messenger_contact_verification_test.go +++ b/protocol/messenger_contact_verification_test.go @@ -195,6 +195,9 @@ func (s *MessengerVerificationRequests) TestAcceptVerificationRequests() { 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().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) s.Require().Equal(challenge, resp.ActivityCenterNotifications()[0].Message.Text) @@ -218,6 +221,9 @@ func (s *MessengerVerificationRequests) TestAcceptVerificationRequests() { s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusACCEPTED) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().Equal(common.ContactVerificationStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) s.Require().Len(resp.Messages(), 1) s.Require().Equal(common.ContactVerificationStateAccepted, resp.Messages()[0].ContactVerificationState) @@ -263,6 +269,9 @@ func (s *MessengerVerificationRequests) TestAcceptVerificationRequests() { s.Require().NotNil(resp.ActivityCenterNotifications()[0].ReplyMessage) s.Require().Empty(resp.ActivityCenterNotifications()[0].ReplyMessage.OutgoingStatus) s.Require().Equal("hello back", resp.ActivityCenterNotifications()[0].ReplyMessage.Text) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) resp, err = s.m.VerifiedTrusted(context.Background(), &requests.VerifiedTrusted{ID: types.FromHex(verificationRequestID)}) s.Require().NoError(err) @@ -311,6 +320,9 @@ func (s *MessengerVerificationRequests) TestTrustedVerificationRequests() { 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().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) s.Require().Equal(challenge, resp.ActivityCenterNotifications()[0].Message.Text) @@ -334,6 +346,9 @@ func (s *MessengerVerificationRequests) TestTrustedVerificationRequests() { s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusACCEPTED) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().Equal(common.ContactVerificationStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) s.Require().Len(resp.Messages(), 1) s.Require().Equal(common.ContactVerificationStateAccepted, resp.Messages()[0].ContactVerificationState) @@ -360,6 +375,9 @@ func (s *MessengerVerificationRequests) TestTrustedVerificationRequests() { s.Require().Len(resp.ActivityCenterNotifications(), 1) s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusACCEPTED) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().Equal(common.ContactVerificationStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) s.Require().NotNil(resp.ActivityCenterNotifications()[0].ReplyMessage) @@ -373,6 +391,9 @@ func (s *MessengerVerificationRequests) TestTrustedVerificationRequests() { s.Require().Len(resp.ActivityCenterNotifications(), 1) s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusTRUSTED) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().Equal(common.ContactVerificationStateTrusted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) s.Require().Len(resp.Messages(), 1) @@ -412,6 +433,9 @@ func (s *MessengerVerificationRequests) TestUnthrustworthyVerificationRequests() 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().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) s.Require().Equal(challenge, resp.ActivityCenterNotifications()[0].Message.Text) @@ -435,6 +459,9 @@ func (s *MessengerVerificationRequests) TestUnthrustworthyVerificationRequests() s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusACCEPTED) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().Equal(common.ContactVerificationStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) s.Require().Len(resp.Messages(), 1) s.Require().Equal(common.ContactVerificationStateAccepted, resp.Messages()[0].ContactVerificationState) @@ -475,6 +502,9 @@ func (s *MessengerVerificationRequests) TestUnthrustworthyVerificationRequests() s.Require().Len(resp.ActivityCenterNotifications(), 1) s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusACCEPTED) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().Equal(common.ContactVerificationStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) s.Require().NotNil(resp.ActivityCenterNotifications()[0].ReplyMessage) @@ -488,6 +518,9 @@ func (s *MessengerVerificationRequests) TestUnthrustworthyVerificationRequests() s.Require().Len(resp.ActivityCenterNotifications(), 1) s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusUNTRUSTWORTHY) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().Equal(common.ContactVerificationStateUntrustworthy, resp.ActivityCenterNotifications()[0].Message.ContactVerificationState) s.Require().Len(resp.Messages(), 1) @@ -526,6 +559,9 @@ func (s *MessengerVerificationRequests) TestDeclineVerificationRequests() { 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().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) s.Require().Equal(challenge, resp.ActivityCenterNotifications()[0].Message.Text) @@ -535,15 +571,15 @@ func (s *MessengerVerificationRequests) TestDeclineVerificationRequests() { s.Require().Equal(resp.Messages()[0].ContactVerificationState, common.ContactVerificationStatePending) // Make sure it's stored and retrieved correctly - notifications, err := theirMessenger.UnreadActivityCenterNotifications( - "", - 4, - []ActivityCenterType{ActivityCenterNotificationTypeContactVerification}, - ) + notification, err := theirMessenger.ActivityCenterNotification(types.FromHex(verificationRequestID)) + s.Require().NoError(err) - s.Require().Len(notifications.Notifications, 1) - s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusPENDING) - s.Require().Equal(notifications.Notifications[0].Message.ContactVerificationState, common.ContactVerificationStatePending) + s.Require().NotNil(notification) + s.Require().Equal(notification.ContactVerificationStatus, verification.RequestStatusPENDING) + s.Require().Equal(notification.Message.ContactVerificationState, common.ContactVerificationStatePending) + s.Require().Equal(notification.Read, false) + s.Require().Equal(notification.Accepted, false) + s.Require().Equal(notification.Dismissed, false) resp, err = theirMessenger.DeclineContactVerificationRequest(context.Background(), verificationRequestID) @@ -561,19 +597,22 @@ func (s *MessengerVerificationRequests) TestDeclineVerificationRequests() { s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusDECLINED) s.Require().Equal(resp.ActivityCenterNotifications()[0].Message.ContactVerificationState, common.ContactVerificationStateDeclined) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, true) s.Require().Len(resp.Messages(), 1) s.Require().Equal(resp.Messages()[0].ContactVerificationState, common.ContactVerificationStateDeclined) // Make sure it's stored and retrieved correctly - notifications, err = theirMessenger.UnreadActivityCenterNotifications( - "", - 4, - []ActivityCenterType{ActivityCenterNotificationTypeContactVerification}, - ) + notification, err = theirMessenger.ActivityCenterNotification(types.FromHex(verificationRequestID)) + s.Require().NoError(err) - s.Require().Len(notifications.Notifications, 1) - s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusDECLINED) - s.Require().Equal(notifications.Notifications[0].Message.ContactVerificationState, common.ContactVerificationStateDeclined) + s.Require().NotNil(notification) + s.Require().Equal(notification.ContactVerificationStatus, verification.RequestStatusDECLINED) + s.Require().Equal(notification.Message.ContactVerificationState, common.ContactVerificationStateDeclined) + s.Require().Equal(notification.Read, true) + s.Require().Equal(notification.Accepted, false) + s.Require().Equal(notification.Dismissed, true) // Wait for the message to reach its destination resp, err = WaitOnMessengerResponse( @@ -594,6 +633,9 @@ func (s *MessengerVerificationRequests) TestDeclineVerificationRequests() { s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), verificationRequestID) s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusDECLINED) s.Require().Equal(resp.ActivityCenterNotifications()[0].Message.ContactVerificationState, common.ContactVerificationStateDeclined) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, true) } func (s *MessengerVerificationRequests) TestCancelVerificationRequest() { @@ -628,6 +670,9 @@ func (s *MessengerVerificationRequests) TestCancelVerificationRequest() { 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().Equal(resp.ActivityCenterNotifications()[0].Read, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) s.Require().Equal(challenge, resp.ActivityCenterNotifications()[0].Message.Text) @@ -643,7 +688,7 @@ func (s *MessengerVerificationRequests) TestCancelVerificationRequest() { []ActivityCenterType{ActivityCenterNotificationTypeContactVerification}, ) s.Require().NoError(err) - s.Require().Len(notifications.Notifications, 1) + s.Require().Greater(len(notifications.Notifications), 0) s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusPENDING) s.Require().Equal(common.ContactVerificationStatePending, notifications.Notifications[0].Message.ContactVerificationState) @@ -670,6 +715,9 @@ func (s *MessengerVerificationRequests) TestCancelVerificationRequest() { s.Require().Equal(resp.VerificationRequests[0].ID, verificationRequestID) s.Require().Equal(resp.ActivityCenterNotifications()[0].Type, ActivityCenterNotificationTypeContactVerification) s.Require().Equal(resp.ActivityCenterNotifications()[0].ContactVerificationStatus, verification.RequestStatusCANCELED) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false) + s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false) s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message) s.Require().Equal(challenge, resp.ActivityCenterNotifications()[0].Message.Text) diff --git a/protocol/messenger_contacts.go b/protocol/messenger_contacts.go index 1246d3387..175d1d035 100644 --- a/protocol/messenger_contacts.go +++ b/protocol/messenger_contacts.go @@ -170,11 +170,15 @@ func (m *Messenger) dismissContactRequest(requestID string, syncing bool) (*Mess } if notification != nil { - err := m.persistence.UpdateActivityCenterNotificationMessage(notification.ID, contactRequest) + notification.Message = contactRequest + notification.Read = true + notification.Dismissed = true + + err = m.persistence.SaveActivityCenterNotification(notification) if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) return nil, err } - notification.Message = contactRequest response.AddActivityCenterNotification(notification) } @@ -262,11 +266,15 @@ func (m *Messenger) updateAcceptedContactRequest(response *MessengerResponse, co } if notification != nil { - err := m.persistence.UpdateActivityCenterNotificationMessage(notification.ID, contactRequest) + notification.Message = contactRequest + notification.Read = true + notification.Accepted = true + + err = m.persistence.SaveActivityCenterNotification(notification) if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) return nil, err } - notification.Message = contactRequest response.AddActivityCenterNotification(notification) } diff --git a/protocol/messenger_handler.go b/protocol/messenger_handler.go index e95667fdb..56ca8d15d 100644 --- a/protocol/messenger_handler.go +++ b/protocol/messenger_handler.go @@ -285,8 +285,9 @@ func (m *Messenger) createContactRequestNotification(contact *Contact, messageSt if err != nil { return err } - // we mark the notification as dismissed + // we mark the notification as dismissed & read notification.Dismissed = true + notification.Read = true // We remove it from the response, since the client has never seen it, better to just remove it found := messageState.Response.RemoveActivityCenterNotification(notification.Message.ID) // Otherwise, it means we have already passed it to the client, so we add it with a `dismissed` flag @@ -351,6 +352,9 @@ func (m *Messenger) createContactRequestNotification(contact *Contact, messageSt Author: messageState.CurrentMessageState.Contact.ID, Timestamp: messageState.CurrentMessageState.WhisperTimestamp, ChatID: contact.ID, + Read: contactRequest.ContactRequestState == common.ContactRequestStateAccepted || contactRequest.ContactRequestState == common.ContactRequestStateDismissed, + Accepted: contactRequest.ContactRequestState == common.ContactRequestStateAccepted, + Dismissed: contactRequest.ContactRequestState == common.ContactRequestStateDismissed, } return m.addActivityCenterNotification(messageState.Response, notification) @@ -1125,10 +1129,10 @@ func (m *Messenger) HandleCommunityRequestToJoin(state *ReceivedMessageState, si MembershipStatus: ActivityCenterMembershipStatusPending, } - saveErr := m.persistence.SaveActivityCenterNotification(notification) - if saveErr != nil { - m.logger.Warn("failed to save notification", zap.Error(saveErr)) - return saveErr + err = m.persistence.SaveActivityCenterNotification(notification) + if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) + return err } state.Response.AddActivityCenterNotification(notification) } else { @@ -1144,10 +1148,10 @@ func (m *Messenger) HandleCommunityRequestToJoin(state *ReceivedMessageState, si } else { notification.MembershipStatus = ActivityCenterMembershipStatusDeclined } - saveErr := m.persistence.SaveActivityCenterNotification(notification) - if saveErr != nil { - m.logger.Warn("failed to update notification", zap.Error(saveErr)) - return saveErr + err = m.persistence.SaveActivityCenterNotification(notification) + if err != nil { + m.logger.Warn("failed to update notification", zap.Error(err)) + return err } state.Response.AddActivityCenterNotification(notification) } @@ -1224,10 +1228,10 @@ func (m *Messenger) HandleCommunityRequestToJoinResponse(state *ReceivedMessageS } else { notification.MembershipStatus = ActivityCenterMembershipStatusDeclined } - saveErr := m.persistence.SaveActivityCenterNotification(notification) - if saveErr != nil { - m.logger.Warn("failed to update notification", zap.Error(saveErr)) - return saveErr + err = m.persistence.SaveActivityCenterNotification(notification) + if err != nil { + m.logger.Warn("failed to update notification", zap.Error(err)) + return err } state.Response.AddActivityCenterNotification(notification) } @@ -1262,10 +1266,10 @@ func (m *Messenger) HandleCommunityRequestToLeave(state *ReceivedMessageState, s CommunityID: string(requestToLeaveProto.CommunityId), } - saveErr := m.persistence.SaveActivityCenterNotification(notification) - if saveErr != nil { - m.logger.Warn("failed to save notification", zap.Error(saveErr)) - return saveErr + err = m.persistence.SaveActivityCenterNotification(notification) + if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) + return err } state.Response.AddActivityCenterNotification(notification) @@ -1699,7 +1703,7 @@ func (m *Messenger) HandleChatMessage(state *ReceivedMessageState) error { func (m *Messenger) addActivityCenterNotification(response *MessengerResponse, notification *ActivityCenterNotification) error { err := m.persistence.SaveActivityCenterNotification(notification) if err != nil { - m.logger.Warn("failed to save notification", zap.Error(err)) + m.logger.Error("failed to save notification", zap.Error(err)) return err } response.AddActivityCenterNotification(notification) diff --git a/protocol/persistence_test.go b/protocol/persistence_test.go index 0c2280997..c8f6c3899 100644 --- a/protocol/persistence_test.go +++ b/protocol/persistence_test.go @@ -1842,8 +1842,9 @@ func TestActivityCenterPersistence(t *testing.T) { require.NoError(t, p.DismissActivityCenterNotifications([]types.HexBytes{nID2})) _, notifications, err = p.ActivityCenterNotifications("", 2) require.NoError(t, err) - // Dismissed notifications should not be returned - require.Len(t, notifications, 0) + + require.Len(t, notifications, 1) + require.True(t, notifications[0].Dismissed) // Insert new notification notification = &ActivityCenterNotification{ @@ -1857,12 +1858,12 @@ func TestActivityCenterPersistence(t *testing.T) { // Mark all as accepted notifications, err = p.AcceptAllActivityCenterNotifications() require.NoError(t, err) - require.Len(t, notifications, 1) + require.Len(t, notifications, 2) _, notifications, err = p.ActivityCenterNotifications("", 2) require.NoError(t, err) - // It should not return those - require.Len(t, notifications, 0) + + require.Len(t, notifications, 1) // Insert new notification notification = &ActivityCenterNotification{ @@ -1877,8 +1878,10 @@ func TestActivityCenterPersistence(t *testing.T) { require.NoError(t, p.DismissAllActivityCenterNotifications()) _, notifications, err = p.ActivityCenterNotifications("", 2) require.NoError(t, err) - // It should not return those - require.Len(t, notifications, 0) + + require.Len(t, notifications, 2) + require.True(t, notifications[0].Dismissed) + require.True(t, notifications[1].Dismissed) } func TestSaveCommunityChat(t *testing.T) {