Class PushNotificationHandler

  • All Implemented Interfaces:
    ICommonServletInterface

    public class PushNotificationHandler
    extends java.lang.Object
    implements ICommonServletInterface
    Push notification handler class used for the web server.

    It handles the following "GET" request: WWW-Authenticate: Basic realm="User Visible Realm", charset="UTF-8"


      Apple Push

      Original information at https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html.

      Downloading Your Website Package

      When a user allows permission to receive push notifications, a POST request is sent to the following URL:

           webServiceURL/version/pushPackages/websitePushID
       

      This POST request contains the following information:

      • In the HTTP body. The same user info JSON object that is passed as the third argument of the requestPermission() call. Use the user info dictionary to identify the user.

      When serving the push package, return application/zip for the Content-type header.

      Registering or Updating Device Permission Policy

      When users first grant permission, or later change their permission levels for your website, a POST request is sent to the following URL:

           webServiceURL/version/devices/deviceToken/registrations/websitePushID
       

      This POST request contains the following information:

      • In the HTTP header. An Authorization header. Its value is the word ApplePushNotifications and the authentication token, separated by a single space. The authentication token is the same token that’s specified in your package’s website.json file. Your web service can use this token to determine which user is registering or updating their permission policy.

      Respond to this request by saving the device token in a database that you can later reference when you send push notifications. Also, change the user’s settings in your database to the values indicated by the parameterized dictionary for the device.

      Forgetting Device Permission Policy

      If a user removes permission of a website in Safari preferences, a DELETE request is sent to the following URL:

           webServiceURL/version/devices/deviceToken/registrations/websitePushID
       

      This DELETE request contains the following information:

      • In the HTTP header. An Authorization header. Its value is the word ApplePushNotifications and the authentication token, separated by a single space. The authentication token is the same token that’s specified in your package’s website.json file. Your web service can use this authentication token to determine which user is removing their permission policy.

      Use this authentication token to remove the device token from your database, as if the device had never registered to your service.

      Logging Errors

      If an error occurs, a POST request is sent to the following URL:

           webServiceURL/version/log
       

      This POST request contains the following information:

      • In the HTTP body. A JSON dictionary containing a single key, named logs, which holds an array of strings describing the errors that occurred.

      Use this endpoint to help you debug your web service implementation. The logs contain a description of the error in a human-readable format. See section Troubleshooting for a list of possible errors.

      Author:
      Christopher Mindus
      • Field Summary

        Fields 
        Modifier and TypeFieldDescription
        static java.lang.StringAPP_ERR_NO_KEYS
        Error message 410 when the 'app_id' is not configured with any Push Messaging keys.
        static java.lang.StringAPP_ID_NOT_FOUND
        Error message when 'app_id' is not found in the server.
        static java.lang.StringAUTH_REALM
        Authentication Realm for Push Notifications.
        static java.lang.StringBASE_REQUEST_URI
        Base URI for IIZI Push API: "/iizi-push/".
        static java.lang.StringGET_SUBSCRIPTIONS
        Get subscriptions for AppID and Topic of the User's all devices or
        static java.lang.StringHEADER
        Header field required for all Push API requests: "X-iizi", containing the requestor's unique Device UUID.
        static java.lang.StringINVALID_SUBSCRIPTION_ERR
        Error message when an invalid subscription is found.
        static java.lang.StringKEYS
        Get server keys for App ID.
        static java.lang.StringNO_SUBSCRIPTIONS_ERR
        Error message when subscriptions are not found.
        static java.lang.StringPUSH
        Send push notification to User for AppID and Topic URI (requires authentication): URI "/iizi-push/push".
        static java.lang.StringRESET
        Resets all subscriptions for a specific device UUID regardless of User/AppID/Topic, or for specified user for all its subscriptions [all AppID's, all Topic's] (requires authentication).
        static java.lang.StringSERVER_NO_KEYS
        Error message 410 when server "app_id='*'" is not configured with any Push Messaging keys.
        static java.lang.StringSUBSCRIBE
        Subscription to AppID and Topic (requires authentication): request URI "/iizi-push/subscribe".
        static java.lang.StringSUBSCRIPTION_COUNT
        Gets the count of all subscriptions.
        static java.lang.StringSUBSCRIPTIONS_LIST
        Get the subscriptions list.
        static java.lang.StringUNSUBSCRIBE
        Unsubscribes a User from AppID and Topic request (requires authentication): URI "/iizi-push/unsubscribe".
      • Method Summary

        All Methods Instance Methods Concrete Methods 
        Modifier and TypeMethodDescription
        intgetSubscriptionCount​(java.lang.String deviceUUID)
        Gets the count of push notification subscriptions for a Device UUID.
        intgetSubscriptionCount​(java.lang.String userID, java.lang.String password, java.lang.String appID, java.lang.String topic)
        Gets the count of push notification subscriptions for a User, app ID and topic.
        booleanhandle​(HttpServletRequest request, HttpServletResponse response)
        Checks if the servlet is handling the request or not.
        intreset​(java.lang.String uuid)
        Performs the reset for a UUID device.
        • Methods inherited from class java.lang.Object

          clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • Field Detail

        • BASE_REQUEST_URI

          public static final java.lang.String BASE_REQUEST_URI
          Base URI for IIZI Push API: "/iizi-push/".
          See Also:
          Constant Field Values
        • HEADER

          public static final java.lang.String HEADER
          Header field required for all Push API requests: "X-iizi", containing the requestor's unique Device UUID.
          See Also:
          Constant Field Values
        • AUTH_REALM

          public static final java.lang.String AUTH_REALM
          Authentication Realm for Push Notifications. When authentication is required, the requesting party should send an "Authorization" header as "Basic <i>authentication</i>" where <i>authentication</i> is the Base64 encoded value of the UTF-8 String userName + ':' + password. The password can be the user's password in clear text or the undecipherable "hashed password" (based on PBKDF2 with Keyed-Hash Message Authentication Code [HMAC] with a SHA-256 hash).
          See Also:
          Constant Field Values
        • KEYS

          public static final java.lang.String KEYS
          Get server keys for App ID.

          URI /iizi-push/keys

          Requires authentication: Yes.

          The request JSON is an Object with the following members:

          • app_id:
            {String} The App ID or "*" for all apps of the server, i.e. the server's configuration for push messaging.

          The response is a JSON Object with the following members:

          • v
            {String} VAPID The ECDSA P-256 public key encoded in Base64.
             
          • a
            {String} Firebase Cloud Messaging ID in Cordova for Android.
             
          • i
            {String} Firebase Cloud Messaging ID in Cordova for iOS.
             
          • w
            {String} Firebase Cloud Messaging ID for the Web.
             
          • s
            {String} Apple Push ID in Safari (macOS and iOS without Cordova).
          See Also:
          Constant Field Values
        • SUBSCRIPTION_COUNT

          public static final java.lang.String SUBSCRIPTION_COUNT
          Gets the count of all subscriptions.

          URI /iizi-push/count

          The count can be retrieved for either:

          • User + AppID + Topic, or
          • Device UUID.

          Authentication required:

          • User + AppID + Topic: Yes.
          • Device UUID: No.

          The request JSON is an Object with the following members:

          • User + AppID + Topic:
             
            • app_id:
              {String} The App ID or "*" for all apps of the server, i.e. the server's configuration for push messaging.
               
            • topic:
              {String} The App ID or "*" for all apps of the server, i.e. the server's configuration for push messaging.

            The response is a JSON Object with the following members:

            • v
              {String} VAPID The ECDSA P-256 public key encoded in Base64.
               
            • a
              {String} Firebase Cloud Messaging ID in Cordova for Android.
               
            • i
              {String} Firebase Cloud Messaging ID in Cordova for iOS.
               
            • w
              {String} Firebase Cloud Messaging ID for the Web.
               
            • s
              {String} Apple Push ID in Safari (macOS and iOS without Cordova).
          See Also:
          Constant Field Values
        • GET_SUBSCRIPTIONS

          public static final java.lang.String GET_SUBSCRIPTIONS
          Get subscriptions for AppID and Topic of the User's all devices or

          Request URI /iizi-push/get_subs

          Requires authentication: Yes.

          See Also:
          Constant Field Values
        • RESET

          public static final java.lang.String RESET
          Resets all subscriptions for a specific device UUID regardless of User/AppID/Topic, or for specified user for all its subscriptions [all AppID's, all Topic's] (requires authentication).

          Request URI /iizi-push/reset

          Requires authentication: Yes.

          If the flag 'device' is 'true', all subscriptions for the device UUID will be used, 'false' means all subscriptions of the user.

          See Also:
          Constant Field Values
        • SUBSCRIPTIONS_LIST

          public static final java.lang.String SUBSCRIPTIONS_LIST
          Get the subscriptions list.

          Request URI /iizi-push/list.

          The request JSON Object have the following members:

          • 'app_id' = {String} App ID
          • 'topic' = {String} Topic

              The reply is a JSON Object as:

              • 'count' = {Number} Count of subscriptions: zero or more in the 'subs' array below
              • 'app_id' = {String} App ID
              • 'topic' = {String} Topic
              • 'subs' = {Array} Array of subscriptions as below

              where each 'subscription' in the 'subs' {Array} is:

              • 'uuid' = {String} device UUID,
              • 'created' = {Number} Time of subscription creation, epoch milliseconds
              • 'vapid' = {Object} A {PushSubscription}.toJSON() object for VAPID-based provider using Service Worker
              • 'android' = {String} Firebase Cloud Messaging ID in Cordova for Android
              • 'ios' = {String} Firebase Cloud Messaging ID in Cordova for iOS
              • 'web' = {String} Firebase Cloud Messaging ID for the Web
              • 'safari' = {String} Apple Push ID in Safari (macOS and iOS without Cordova)
          See Also:
          Constant Field Values
        • SUBSCRIBE

          public static final java.lang.String SUBSCRIBE
          Subscription to AppID and Topic (requires authentication): request URI "/iizi-push/subscribe".
          See Also:
          Constant Field Values
        • UNSUBSCRIBE

          public static final java.lang.String UNSUBSCRIBE
          Unsubscribes a User from AppID and Topic request (requires authentication): URI "/iizi-push/unsubscribe".

          If the flag 'all' is 'true', all subscriptions from all devices of the user will be unsubscribed.

          See Also:
          Constant Field Values
        • PUSH

          public static final java.lang.String PUSH
          Send push notification to User for AppID and Topic URI (requires authentication): URI "/iizi-push/push".
          See Also:
          Constant Field Values
        • APP_ID_NOT_FOUND

          public static final java.lang.String APP_ID_NOT_FOUND
          Error message when 'app_id' is not found in the server.
          See Also:
          Constant Field Values
        • SERVER_NO_KEYS

          public static final java.lang.String SERVER_NO_KEYS
          Error message 410 when server "app_id='*'" is not configured with any Push Messaging keys.
          See Also:
          Constant Field Values
        • APP_ERR_NO_KEYS

          public static final java.lang.String APP_ERR_NO_KEYS
          Error message 410 when the 'app_id' is not configured with any Push Messaging keys.
          See Also:
          Constant Field Values
        • NO_SUBSCRIPTIONS_ERR

          public static final java.lang.String NO_SUBSCRIPTIONS_ERR
          Error message when subscriptions are not found.
          See Also:
          Constant Field Values
        • INVALID_SUBSCRIPTION_ERR

          public static final java.lang.String INVALID_SUBSCRIPTION_ERR
          Error message when an invalid subscription is found.
          See Also:
          Constant Field Values
      • Method Detail

        • reset

          public int reset​(java.lang.String uuid)
                    throws java.sql.SQLException
          Performs the reset for a UUID device. All subscriptions will be removed.
          Parameters:
          uuid - The device UUID.
          Returns:
          The count of removed subscriptions.
          Throws:
          java.sql.SQLException - For SQL errors.
        • getSubscriptionCount

          public int getSubscriptionCount​(java.lang.String deviceUUID)
                                   throws java.sql.SQLException
          Gets the count of push notification subscriptions for a Device UUID.
          Parameters:
          deviceUUID - The device UUID.
          Returns:
          The count of subscriptions matching this Device UUID.
          Throws:
          java.lang.NullPointerException - If deviceUUID is null.
          java.lang.IllegalArgumentException - If the deviceUUID does not conform the UUID string representation UUID.toString().
          java.sql.SQLException - For SQL errors.
        • getSubscriptionCount

          public int getSubscriptionCount​(java.lang.String userID,
                                          java.lang.String password,
                                          java.lang.String appID,
                                          java.lang.String topic)
                                   throws java.sql.SQLException
          Gets the count of push notification subscriptions for a User, app ID and topic.
          Parameters:
          userID - The user ID, cannot be null.
          password - The password in clear text or a hashed password, cannot be null.
          appID - The application ID, cannot be null, "*" for all applications.
          topic - The topic, cannot be null but empty string for none.
          Returns:
          The count of subscriptions.
          Throws:
          java.sql.SQLException - For SQL errors.
          NotFoundException - If the userID is not found, or if the password doesn't match.
          java.lang.NullPointerException - If any parameter is null.