diff --git a/protocol/messenger.go b/protocol/messenger.go index 39f6b2a73..e075231b4 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -3044,7 +3044,7 @@ func (m *Messenger) AddPushNotificationServer(ctx context.Context, publicKey *ec } func (m *Messenger) UnregisterFromPushNotifications(ctx context.Context) error { - return nil + return m.pushNotificationClient.Unregister() } func (m *Messenger) DisableSendingPushNotifications() error { diff --git a/protocol/push_notification_client/client.go b/protocol/push_notification_client/client.go index 5f13c30b6..3a706685e 100644 --- a/protocol/push_notification_client/client.go +++ b/protocol/push_notification_client/client.go @@ -456,6 +456,15 @@ func (c *Client) buildPushNotificationRegistrationMessage(contactIDs []*ecdsa.Pu return options, nil } +func (c *Client) buildPushNotificationUnregisterMessage() *protobuf.PushNotificationRegistration { + options := &protobuf.PushNotificationRegistration{ + Version: c.getVersion(), + InstallationId: c.config.InstallationID, + Unregister: true, + } + return options +} + // shouldRefreshToken tells us whether we should pull a new token, that's only necessary when a contact is removed func (c *Client) shouldRefreshToken(oldContactIDs, newContactIDs []*ecdsa.PublicKey) bool { newContactIDsMap := make(map[string]bool) @@ -481,6 +490,29 @@ func shouldRetryRegisteringWithServer(server *PushNotificationServer) bool { return time.Now().Unix() < nextServerRetry(server) } +func (c *Client) resetServers() error { + servers, err := c.persistence.GetServers() + if err != nil { + return err + } + for _, server := range servers { + + // Reset server registration data + server.Registered = false + server.RegisteredAt = 0 + server.RetryCount += 1 + server.LastRetriedAt = time.Now().Unix() + server.AccessToken = "" + + if err := c.persistence.UpsertServer(server); err != nil { + return err + } + + } + + return nil +} + func (c *Client) registerWithServer(registration *protobuf.PushNotificationRegistration, server *PushNotificationServer) error { // Reset server registration data server.Registered = false @@ -576,6 +608,41 @@ func (c *Client) registrationLoop() error { } } +func (c *Client) Unregister() error { + // stop registration loop + c.stopRegistrationLoop() + + registration := c.buildPushNotificationUnregisterMessage() + err := c.SaveLastPushNotificationRegistration(registration, nil) + if err != nil { + return err + } + // Reset servers + err = c.resetServers() + if err != nil { + return err + } + + // and asynchronously register + c.startRegistrationLoop() + return nil +} + +func (c *Client) SaveLastPushNotificationRegistration(registration *protobuf.PushNotificationRegistration, contactIDs []*ecdsa.PublicKey) error { + // stop registration loop + c.stopRegistrationLoop() + + err := c.persistence.SaveLastPushNotificationRegistration(registration, contactIDs) + if err != nil { + return err + } + c.lastPushNotificationRegistration = registration + c.lastContactIDs = contactIDs + + c.startRegistrationLoop() + return nil +} + func (c *Client) Register(deviceToken string, contactIDs []*ecdsa.PublicKey, mutedChatIDs []string) ([]*PushNotificationServer, error) { // stop registration loop c.stopRegistrationLoop() @@ -595,6 +662,11 @@ func (c *Client) Register(deviceToken string, contactIDs []*ecdsa.PublicKey, mut return nil, err } + err = c.SaveLastPushNotificationRegistration(registration, contactIDs) + if err != nil { + return nil, err + } + var serverPublicKeys []*ecdsa.PublicKey for _, server := range servers { err := c.registerWithServer(registration, server) diff --git a/protocol/push_notification_server/server_test.go b/protocol/push_notification_server/server_test.go index 4f31070e5..e895af70f 100644 --- a/protocol/push_notification_server/server_test.go +++ b/protocol/push_notification_server/server_test.go @@ -177,9 +177,7 @@ func (s *ServerSuite) TestPushNotificationServerValidateRegistration() { // Unregistering message payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{ - TokenType: protobuf.PushNotificationRegistration_APN_TOKEN, InstallationId: s.installationID, - Grant: s.grant, Unregister: true, Version: 1, })