Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions protocol/protobuf/push_notifications.proto
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ message PushNotification {
MESSAGE = 1;
MENTION = 2;
REQUEST_TO_JOIN_COMMUNITY = 3;
CONTACT_REQUEST = 4;
}
bytes author = 7;
}
Expand Down
9 changes: 7 additions & 2 deletions protocol/pushnotificationclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1073,8 +1073,13 @@ func (c *Client) handleDirectMessageSent(sentMessage *messagingevents.SentMessag
chatID = message.ChatId
}

notificationType := protobuf.PushNotification_MESSAGE
if message.ContentType == protobuf.ChatMessage_CONTACT_REQUEST {
notificationType = protobuf.PushNotification_CONTACT_REQUEST
}

// we send the notifications and return the info of the devices notified
infos, err := c.SendNotification(publicKey, installationIDs, trackedMessageIDs[0], chatID, protobuf.PushNotification_MESSAGE)
infos, err := c.SendNotification(publicKey, installationIDs, trackedMessageIDs[0], chatID, notificationType)
if err != nil {
return err
}
Expand All @@ -1084,7 +1089,7 @@ func (c *Client) handleDirectMessageSent(sentMessage *messagingevents.SentMessag
for _, messageID := range trackedMessageIDs {

c.config.Logger.Debug("marking as sent ", zap.String("messageID", types.EncodeHex(messageID)), zap.String("id", i.InstallationID))
if err := c.notifiedOn(publicKey, i.InstallationID, messageID, chatID, protobuf.PushNotification_MESSAGE); err != nil {
if err := c.notifiedOn(publicKey, i.InstallationID, messageID, chatID, notificationType); err != nil {
return err
}

Expand Down
10 changes: 8 additions & 2 deletions protocol/pushnotificationserver/gorush.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import (
const defaultNewMessageNotificationText = "New message in Messenger"
const defaultMentionNotificationText = "New mention or reply in Communities"
const defaultRequestToJoinCommunityNotificationText = "Someone requested to join a community you are an admin of"
const defaultContactRequestNotificationText = "Someone sent you a contact request"

const deepLinkChats = "status-app://chats" // plain messages -> messenger
const deepLinkActivityCenter = "status-app://ac" // mentions, community requests, etc. -> activity center
const deepLinkChats = "status-app://chats" // plain messages -> messenger
const deepLinkActivityCenter = "status-app://ac" // mentions, community requests, etc. -> activity center
const deepLinkContactRequests = "status-app://contact-requests" // contact requests -> activity center contact requests

type GoRushRequestData struct {
EncryptedMessage string `json:"encryptedMessage"`
Expand Down Expand Up @@ -67,6 +69,8 @@ func PushNotificationRegistrationToGoRushRequest(requestAndRegistrations []*Requ
text = defaultNewMessageNotificationText
} else if request.Type == protobuf.PushNotification_REQUEST_TO_JOIN_COMMUNITY {
text = defaultRequestToJoinCommunityNotificationText
} else if request.Type == protobuf.PushNotification_CONTACT_REQUEST {
text = defaultContactRequestNotificationText
} else {
text = defaultMentionNotificationText
}
Expand All @@ -78,6 +82,8 @@ func PushNotificationRegistrationToGoRushRequest(requestAndRegistrations []*Requ
pushType = "alert"
if request.Type == protobuf.PushNotification_MESSAGE {
deepLink = deepLinkChats
} else if request.Type == protobuf.PushNotification_CONTACT_REQUEST {
deepLink = deepLinkContactRequests
} else {
deepLink = deepLinkActivityCenter
}
Expand Down
29 changes: 29 additions & 0 deletions protocol/pushnotificationserver/gorush_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ func TestPushNotificationRegistrationToGoRushRequest(t *testing.T) {
TokenType: protobuf.PushNotificationRegistration_FIREBASE_TOKEN,
},
},
{
Request: &protobuf.PushNotification{
ChatId: chatID,
Type: protobuf.PushNotification_CONTACT_REQUEST,
PublicKey: publicKey2,
InstallationId: installationID3,
Message: message3,
},
Registration: &protobuf.PushNotificationRegistration{
DeviceToken: token3,
TokenType: protobuf.PushNotificationRegistration_APN_TOKEN,
},
},
}

expectedRequests := &GoRushRequest{
Expand Down Expand Up @@ -108,6 +121,21 @@ func TestPushNotificationRegistrationToGoRushRequest(t *testing.T) {
PublicKey: types.EncodeHex(publicKey2),
},
},
{
Tokens: []string{token3},
Platform: platform1,
Message: defaultContactRequestNotificationText,
ContentAvailable: true,
Sound: "default",
Priority: "high",
PushType: "alert",
Data: &GoRushRequestData{
EncryptedMessage: hexMessage3,
ChatID: types.EncodeHex(chatID),
PublicKey: types.EncodeHex(publicKey2),
DeepLink: deepLinkContactRequests,
},
},
},
}
actualRequests := PushNotificationRegistrationToGoRushRequest(requestAndRegistrations)
Expand Down Expand Up @@ -153,6 +181,7 @@ func TestGoRushRequestDeepLinkByType(t *testing.T) {
{"message", protobuf.PushNotification_MESSAGE, deepLinkChats},
{"mention", protobuf.PushNotification_MENTION, deepLinkActivityCenter},
{"community request", protobuf.PushNotification_REQUEST_TO_JOIN_COMMUNITY, deepLinkActivityCenter},
{"contact request", protobuf.PushNotification_CONTACT_REQUEST, deepLinkContactRequests},
{"unknown", protobuf.PushNotification_UNKNOWN_PUSH_NOTIFICATION_TYPE, deepLinkActivityCenter},
}
for _, tc := range cases {
Expand Down
13 changes: 12 additions & 1 deletion protocol/pushnotificationserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ func (s *Server) buildPushNotificationReport(pn *protobuf.PushNotification, regi
} else if registration.AccessToken != pn.AccessToken {
s.config.Logger.Debug("invalid token")
report.Error = protobuf.PushNotificationReport_WRONG_TOKEN
} else if (s.isMessageNotification(pn) && !s.isValidMessageNotification(pn, registration)) || (s.isMentionNotification(pn) && !s.isValidMentionNotification(pn, registration)) || (s.isRequestToJoinCommunityNotification(pn) && !s.isValidRequestToJoinCommunityNotification(pn, registration)) {
} else if (s.isMessageNotification(pn) && !s.isValidMessageNotification(pn, registration)) || (s.isMentionNotification(pn) && !s.isValidMentionNotification(pn, registration)) || (s.isRequestToJoinCommunityNotification(pn) && !s.isValidRequestToJoinCommunityNotification(pn, registration)) || (s.isContactRequestNotification(pn) && !s.isValidContactRequestNotification(pn, registration)) {
s.config.Logger.Debug("filtered notification")
// We report as successful but don't send the notification
// for privacy reasons, as otherwise we would disclose that
Expand Down Expand Up @@ -565,3 +565,14 @@ func (s *Server) isRequestToJoinCommunityNotification(pn *protobuf.PushNotificat
func (s *Server) isValidRequestToJoinCommunityNotification(pn *protobuf.PushNotification, registration *protobuf.PushNotificationRegistration) bool {
return s.isRequestToJoinCommunityNotification(pn) && !s.contains(registration.BlockedChatList, pn.Author)
}

func (s *Server) isContactRequestNotification(pn *protobuf.PushNotification) bool {
return pn.Type == protobuf.PushNotification_CONTACT_REQUEST
}

// isValidContactRequestNotification checks:
// this is a contact request
// the author is not blocked
func (s *Server) isValidContactRequestNotification(pn *protobuf.PushNotification, registration *protobuf.PushNotificationRegistration) bool {
return s.isContactRequestNotification(pn) && !s.contains(registration.BlockedChatList, pn.Author)
}
33 changes: 33 additions & 0 deletions protocol/pushnotificationserver/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,12 @@ func (s *ServerSuite) TestBuildPushNotificationReport() {
ChatId: chatID,
AccessToken: accessToken,
}
validContactRequestPN := &protobuf.PushNotification{
Type: protobuf.PushNotification_CONTACT_REQUEST,
ChatId: chatID,
Author: author,
AccessToken: accessToken,
}
validRegistration := &protobuf.PushNotificationRegistration{
AccessToken: accessToken,
BlockedChatList: blockedChatList,
Expand Down Expand Up @@ -733,6 +739,17 @@ func (s *ServerSuite) TestBuildPushNotificationReport() {
},
},
},
{
name: "valid contact request",
pn: validContactRequestPN,
registration: validRegistration,
expectedResponse: &reportResult{
sendNotification: true,
report: &protobuf.PushNotificationReport{
Success: true,
},
},
},
{
name: "unknow push notification",
pn: &protobuf.PushNotification{
Expand Down Expand Up @@ -884,6 +901,22 @@ func (s *ServerSuite) TestBuildPushNotificationReport() {
},
},
},
{
name: "blocked contact request author",
pn: &protobuf.PushNotification{
Type: protobuf.PushNotification_CONTACT_REQUEST,
Author: blockedAuthor,
ChatId: chatID,
AccessToken: accessToken,
},
registration: validRegistration,
expectedResponse: &reportResult{
sendNotification: false,
report: &protobuf.PushNotificationReport{
Success: true,
},
},
},
{
name: "blocked mentions",
pn: &protobuf.PushNotification{
Expand Down
7 changes: 4 additions & 3 deletions tests-functional/tests/test_push_notification_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

APN_TOPIC = "im.status.ethereum"
DEFAULT_PUSH_MESSAGE = "New message in Messenger"
CONTACT_REQUEST_PUSH_MESSAGE = "Someone sent you a contact request"


@pytest.fixture
Expand All @@ -37,14 +38,14 @@ def push_notification_server(gorush_stub):
server.shutdown()


def expect_push_notification(gorush, sender, receiver):
def expect_push_notification(gorush, sender, receiver, expected_message=DEFAULT_PUSH_MESSAGE):
requests = gorush.wait_for_requests()
assert len(requests) == 1, "Expected 1 push notification to be received"

push = requests[0]
assert len(push["tokens"]) == 1 and push["tokens"][0] == receiver.device_id, "Expected only Bob device_id in push notification tokens"
assert push["platform"] == receiver.device_platform.value
assert push["message"] == DEFAULT_PUSH_MESSAGE
assert push["message"] == expected_message
assert push["data"]["publicKey"] == keys.shake256(bytes.fromhex(receiver.compressed_public_key()[2:]))
assert push["data"]["chatId"] == keys.shake256(sender.public_key.encode("utf-8"))

Expand Down Expand Up @@ -77,7 +78,7 @@ def test_push_notification_delivery(self, push_notification_server, sender, rece

# Make contacts, this should force delivery of a push notification
messenger.make_contacts(sender, receiver)
expect_push_notification(gorush, sender, receiver)
expect_push_notification(gorush, sender, receiver, CONTACT_REQUEST_PUSH_MESSAGE)

# Send a message from Alice to Bob
sender.wakuext_service.send_one_to_one_message(receiver.public_key, f"Message {uuid.uuid4()}")
Expand Down
Loading