web-push 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.github/workflows/ci.yml +22 -0
 - data/.gitignore +1 -9
 - data/README.md +48 -211
 - data/lib/web_push/encryption.rb +3 -5
 - data/lib/web_push/request.rb +5 -33
 - data/lib/web_push/vapid_key.rb +8 -3
 - data/lib/web_push/version.rb +1 -1
 - data/lib/web_push.rb +2 -3
 - data/spec/spec_helper.rb +1 -2
 - data/spec/web_push/encryption_spec.rb +3 -3
 - data/spec/web_push/request_spec.rb +1 -46
 - data/spec/web_push/vapid_key_spec.rb +29 -0
 - data/spec/web_push_spec.rb +4 -4
 - data/web-push.gemspec +5 -6
 - metadata +19 -56
 - data/.rspec +0 -2
 - data/.rubocop.yml +0 -30
 - data/.travis.yml +0 -24
 - data/CHANGELOG.md +0 -183
 - data/Rakefile +0 -8
 - data/bin/console +0 -14
 - data/bin/rake +0 -16
 - data/bin/rspec +0 -16
 - data/bin/setup +0 -8
 - data/lib/tasks/web_push.rake +0 -14
 - data/lib/web_push/railtie.rb +0 -9
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 0ce88ebd076b697f1933784607d0e7d743e66c0fe2a3522b2d91fbf8f7d674b4
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: b8eede6dba32f1933ab8ea706dd27dcc7d54fcc2a1bafb6c63249accc2e335f5
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 8cfedadf6aa0335ac451df3b47358b801802aed8e81f49ab869826eef67ff64bb06950095fd8764c259b37165dd5cdd7537521f23957cde359bb41e14661f53d
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 8cb1d4e8711c0356dd22b10befaf535cbe9fbc3878bb18414f708dfa378472f2728d576641831822c63928320c10b79ded83cc888542280a9161eb83b194df86
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            name: CI
         
     | 
| 
      
 2 
     | 
    
         
            +
            on:
         
     | 
| 
      
 3 
     | 
    
         
            +
              push:
         
     | 
| 
      
 4 
     | 
    
         
            +
                branches: [ master ]
         
     | 
| 
      
 5 
     | 
    
         
            +
              pull_request:
         
     | 
| 
      
 6 
     | 
    
         
            +
                branches: [ master ]
         
     | 
| 
      
 7 
     | 
    
         
            +
            jobs:
         
     | 
| 
      
 8 
     | 
    
         
            +
              test:
         
     | 
| 
      
 9 
     | 
    
         
            +
                runs-on: ubuntu-latest
         
     | 
| 
      
 10 
     | 
    
         
            +
                strategy:
         
     | 
| 
      
 11 
     | 
    
         
            +
                  fail-fast: false
         
     | 
| 
      
 12 
     | 
    
         
            +
                  matrix:
         
     | 
| 
      
 13 
     | 
    
         
            +
                    ruby-version: ['3.0', '3.1']
         
     | 
| 
      
 14 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 15 
     | 
    
         
            +
                - uses: actions/checkout@v3
         
     | 
| 
      
 16 
     | 
    
         
            +
                - name: Set up Ruby
         
     | 
| 
      
 17 
     | 
    
         
            +
                  uses: ruby/setup-ruby@v1
         
     | 
| 
      
 18 
     | 
    
         
            +
                  with:
         
     | 
| 
      
 19 
     | 
    
         
            +
                    ruby-version: ${{ matrix.ruby-version }}
         
     | 
| 
      
 20 
     | 
    
         
            +
                    bundler-cache: true
         
     | 
| 
      
 21 
     | 
    
         
            +
                - name: Run tests
         
     | 
| 
      
 22 
     | 
    
         
            +
                  run: bundle exec rspec
         
     | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,45 +1,35 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # WebPush
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            [](https://travis-ci.org/zaru/webpush)
         
     | 
| 
       6 
     | 
    
         
            -
            [](https://badge.fury.io/rb/webpush)
         
     | 
| 
      
 3 
     | 
    
         
            +
            [](https://badge.fury.io/rb/web-push)
         
     | 
| 
      
 4 
     | 
    
         
            +
            
         
     | 
| 
       7 
5 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            This gem makes it possible to send push messages to web browsers from Ruby backends using the [Web Push Protocol](https:// 
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
            Payload is supported by Chrome 50+, Firefox 48+, Edge 79+.
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            [webpush Demo app here (building by Sinatra app).](https://github.com/zaru/webpush_demo_ruby)
         
     | 
| 
      
 6 
     | 
    
         
            +
            This gem makes it possible to send push messages to web browsers from Ruby backends using the [Web Push Protocol](https://datatracker.ietf.org/doc/html/rfc8030). It supports [Message Encryption for Web Push](https://datatracker.ietf.org/doc/html/rfc8291) and [VAPID](https://datatracker.ietf.org/doc/html/rfc8292).
         
     | 
| 
       13 
7 
     | 
    
         | 
| 
       14 
8 
     | 
    
         
             
            ## Installation
         
     | 
| 
       15 
9 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
            Add this line to  
     | 
| 
      
 10 
     | 
    
         
            +
            Add this line to the Gemfile:
         
     | 
| 
       17 
11 
     | 
    
         | 
| 
       18 
12 
     | 
    
         
             
            ```ruby
         
     | 
| 
       19 
13 
     | 
    
         
             
            gem 'web-push'
         
     | 
| 
       20 
14 
     | 
    
         
             
            ```
         
     | 
| 
       21 
15 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                $ bundle
         
     | 
| 
      
 16 
     | 
    
         
            +
            Or install the gem:
         
     | 
| 
       25 
17 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
      
 18 
     | 
    
         
            +
            ```console
         
     | 
| 
      
 19 
     | 
    
         
            +
            $ gem install web-push
         
     | 
| 
      
 20 
     | 
    
         
            +
            ```
         
     | 
| 
       29 
21 
     | 
    
         | 
| 
       30 
22 
     | 
    
         
             
            ## Usage
         
     | 
| 
       31 
23 
     | 
    
         | 
| 
       32 
24 
     | 
    
         
             
            Sending a web push message to a visitor of your website requires a number of steps:
         
     | 
| 
       33 
25 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
            1.  
     | 
| 
       35 
     | 
    
         
            -
            2.  
     | 
| 
       36 
     | 
    
         
            -
            3.  
     | 
| 
       37 
     | 
    
         
            -
            4. Your server uses the `web-push` gem to send a notification with the `subscription` obtained from the client and an optional payload (the message).
         
     | 
| 
       38 
     | 
    
         
            -
            5. Your service worker is set up to receive `'push'` events. To trigger a desktop notification, the user has accepted the prompt to receive notifications from your site.
         
     | 
| 
      
 26 
     | 
    
         
            +
            1. In the user's web browser, a `serviceWorker` is installed and activated and its `pushManager` property is subscribed to push events with your VAPID public key, which creates a `subscription` JSON object on the client side.
         
     | 
| 
      
 27 
     | 
    
         
            +
            2. Your server uses the `web-push` gem to send a notification with the `subscription` obtained from the client and an optional payload (the message).
         
     | 
| 
      
 28 
     | 
    
         
            +
            3. Your service worker is set up to receive `'push'` events. To trigger a desktop notification, the user has accepted the prompt to receive notifications from your site.
         
     | 
| 
       39 
29 
     | 
    
         | 
| 
       40 
30 
     | 
    
         
             
            ### Generating VAPID keys
         
     | 
| 
       41 
31 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
            Use `web-push` to generate a VAPID key that has both a `public_key` and `private_key`  
     | 
| 
      
 32 
     | 
    
         
            +
            Use `web-push` to generate a VAPID key pair (that has both a `public_key` and `private_key`) and save it on the server side.
         
     | 
| 
       43 
33 
     | 
    
         | 
| 
       44 
34 
     | 
    
         
             
            ```ruby
         
     | 
| 
       45 
35 
     | 
    
         
             
            # One-time, on the server
         
     | 
| 
         @@ -53,64 +43,25 @@ vapid_key.private_key 
     | 
|
| 
       53 
43 
     | 
    
         
             
            vapid_key.to_pem
         
     | 
| 
       54 
44 
     | 
    
         
             
            ```
         
     | 
| 
       55 
45 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
            ### Declaring manifest.json
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
            Check out the [Web Manifest docs](https://developer.mozilla.org/en-US/docs/Web/Manifest) for details on what to include in your `manifest.json` file. If using VAPID, no app credentials are needed.
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
            ```javascript
         
     | 
| 
       61 
     | 
    
         
            -
            {
         
     | 
| 
       62 
     | 
    
         
            -
              "name": "My Website"
         
     | 
| 
       63 
     | 
    
         
            -
            }
         
     | 
| 
       64 
     | 
    
         
            -
            ```
         
     | 
| 
       65 
     | 
    
         
            -
            For Chrome web push, add the GCM sender id to a `manifest.json`.
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
            ```javascript
         
     | 
| 
       68 
     | 
    
         
            -
            {
         
     | 
| 
       69 
     | 
    
         
            -
              "name": "My Website",
         
     | 
| 
       70 
     | 
    
         
            -
              "gcm_sender_id": "1006629465533"
         
     | 
| 
       71 
     | 
    
         
            -
            }
         
     | 
| 
       72 
     | 
    
         
            -
            ```
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
            The file is served within the scope of your service worker script, like at the root, and link to it somewhere in the `<head>` tag:
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
            ```html
         
     | 
| 
       77 
     | 
    
         
            -
            <!-- index.html -->
         
     | 
| 
       78 
     | 
    
         
            -
            <link rel="manifest" href="/manifest.json" />
         
     | 
| 
       79 
     | 
    
         
            -
            ```
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
46 
     | 
    
         
             
            ### Installing a service worker
         
     | 
| 
       82 
47 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
            Your application  
     | 
| 
      
 48 
     | 
    
         
            +
            Your application must use JavaScript to register a service worker script at an appropriate scope (root is recommended).
         
     | 
| 
       84 
49 
     | 
    
         | 
| 
       85 
50 
     | 
    
         
             
            ```javascript
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
            // Register the serviceWorker script at /serviceworker.js from your server if supported
         
     | 
| 
       88 
     | 
    
         
            -
            if (navigator.serviceWorker) {
         
     | 
| 
       89 
     | 
    
         
            -
              navigator.serviceWorker.register('/serviceworker.js')
         
     | 
| 
       90 
     | 
    
         
            -
              .then(function(reg) {
         
     | 
| 
       91 
     | 
    
         
            -
                 console.log('Service worker change, registered the service worker');
         
     | 
| 
       92 
     | 
    
         
            -
              });
         
     | 
| 
       93 
     | 
    
         
            -
            }
         
     | 
| 
       94 
     | 
    
         
            -
            // Otherwise, no push notifications :(
         
     | 
| 
       95 
     | 
    
         
            -
            else {
         
     | 
| 
       96 
     | 
    
         
            -
              console.error('Service worker is not supported in this browser');
         
     | 
| 
       97 
     | 
    
         
            -
            }
         
     | 
| 
      
 51 
     | 
    
         
            +
            navigator.serviceWorker.register('/service-worker.js')
         
     | 
| 
       98 
52 
     | 
    
         
             
            ```
         
     | 
| 
       99 
53 
     | 
    
         | 
| 
       100 
54 
     | 
    
         
             
            ### Subscribing to push notifications
         
     | 
| 
       101 
55 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
            The VAPID public key you generated earlier is made available to the client as a `UInt8Array`. To do this, one way would be to expose the urlsafe-decoded bytes from Ruby to JavaScript when rendering the HTML template. (Global variables used here for simplicity).
         
     | 
| 
      
 56 
     | 
    
         
            +
            The VAPID public key you generated earlier is made available to the client as a `UInt8Array`. To do this, one way would be to expose the urlsafe-decoded bytes from Ruby to JavaScript when rendering the HTML template.
         
     | 
| 
       105 
57 
     | 
    
         | 
| 
       106 
58 
     | 
    
         
             
            ```javascript
         
     | 
| 
       107 
59 
     | 
    
         
             
            window.vapidPublicKey = new Uint8Array(<%= Base64.urlsafe_decode64(ENV['VAPID_PUBLIC_KEY']).bytes %>);
         
     | 
| 
       108 
60 
     | 
    
         
             
            ```
         
     | 
| 
       109 
61 
     | 
    
         | 
| 
       110 
     | 
    
         
            -
            Your  
     | 
| 
      
 62 
     | 
    
         
            +
            Your JavaScript code uses the `pushManager` interface to subscribe to push notifications, passing the VAPID public key to the subscription settings.
         
     | 
| 
       111 
63 
     | 
    
         | 
| 
       112 
64 
     | 
    
         
             
            ```javascript
         
     | 
| 
       113 
     | 
    
         
            -
            // application.js
         
     | 
| 
       114 
65 
     | 
    
         
             
            // When serviceWorker is supported, installed, and activated,
         
     | 
| 
       115 
66 
     | 
    
         
             
            // subscribe the pushManager property with the vapidPublicKey
         
     | 
| 
       116 
67 
     | 
    
         
             
            navigator.serviceWorker.ready.then((serviceWorkerRegistration) => {
         
     | 
| 
         @@ -122,120 +73,49 @@ navigator.serviceWorker.ready.then((serviceWorkerRegistration) => { 
     | 
|
| 
       122 
73 
     | 
    
         
             
            });
         
     | 
| 
       123 
74 
     | 
    
         
             
            ```
         
     | 
| 
       124 
75 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
            #### Without VAPID
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
            If you will not be sending VAPID details, then there is no need generate VAPID keys, and the `applicationServerKey` parameter may be omitted from the `pushManager.subscribe` call.
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
            ```javascript
         
     | 
| 
       130 
     | 
    
         
            -
            // application.js
         
     | 
| 
       131 
     | 
    
         
            -
            // When serviceWorker is supported, installed, and activated,
         
     | 
| 
       132 
     | 
    
         
            -
            // subscribe the pushManager property with the vapidPublicKey
         
     | 
| 
       133 
     | 
    
         
            -
            navigator.serviceWorker.ready.then((serviceWorkerRegistration) => {
         
     | 
| 
       134 
     | 
    
         
            -
              serviceWorkerRegistration.pushManager
         
     | 
| 
       135 
     | 
    
         
            -
              .subscribe({
         
     | 
| 
       136 
     | 
    
         
            -
                userVisibleOnly: true
         
     | 
| 
       137 
     | 
    
         
            -
              });
         
     | 
| 
       138 
     | 
    
         
            -
            });
         
     | 
| 
       139 
     | 
    
         
            -
            ```
         
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
76 
     | 
    
         
             
            ### Triggering a web push notification
         
     | 
| 
       142 
77 
     | 
    
         | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
            ```javascript
         
     | 
| 
       146 
     | 
    
         
            -
            // application.js
         
     | 
| 
       147 
     | 
    
         
            -
            // Send the subscription and message from the client for the backend
         
     | 
| 
       148 
     | 
    
         
            -
            // to set up a push notification
         
     | 
| 
       149 
     | 
    
         
            -
            $(".web-push-button").on("click", (e) => {
         
     | 
| 
       150 
     | 
    
         
            -
              navigator.serviceWorker.ready
         
     | 
| 
       151 
     | 
    
         
            -
              .then((serviceWorkerRegistration) => {
         
     | 
| 
       152 
     | 
    
         
            -
                serviceWorkerRegistration.pushManager.getSubscription()
         
     | 
| 
       153 
     | 
    
         
            -
                .then((subscription) => {
         
     | 
| 
       154 
     | 
    
         
            -
                  $.post("/push", { subscription: subscription.toJSON(), message: "You clicked a button!" });
         
     | 
| 
       155 
     | 
    
         
            -
                });
         
     | 
| 
       156 
     | 
    
         
            -
              });
         
     | 
| 
       157 
     | 
    
         
            -
            });
         
     | 
| 
       158 
     | 
    
         
            -
            ```
         
     | 
| 
      
 78 
     | 
    
         
            +
            In order to send web push notifications, the push subscription must be stored in the backend. Get the subscription with `pushManager.getSubscription()` and store it in your database.
         
     | 
| 
       159 
79 
     | 
    
         | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
      
 80 
     | 
    
         
            +
            Then you can use this gem to send web push messages:
         
     | 
| 
       161 
81 
     | 
    
         | 
| 
       162 
82 
     | 
    
         
             
            ```ruby
         
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
               
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
                 
     | 
| 
       170 
     | 
    
         
            -
                 
     | 
| 
       171 
     | 
    
         
            -
                 
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
                ssl_timeout: 5, # value for Net::HTTP#ssl_timeout=, optional
         
     | 
| 
       178 
     | 
    
         
            -
                open_timeout: 5, # value for Net::HTTP#open_timeout=, optional
         
     | 
| 
       179 
     | 
    
         
            -
                read_timeout: 5 # value for Net::HTTP#read_timeout=, optional
         
     | 
| 
       180 
     | 
    
         
            -
              )
         
     | 
| 
       181 
     | 
    
         
            -
            end
         
     | 
| 
      
 83 
     | 
    
         
            +
            WebPush.payload_send(
         
     | 
| 
      
 84 
     | 
    
         
            +
              message: message,
         
     | 
| 
      
 85 
     | 
    
         
            +
              endpoint: subscription['endpoint'],
         
     | 
| 
      
 86 
     | 
    
         
            +
              p256dh: subscription['keys']['p256dh'],
         
     | 
| 
      
 87 
     | 
    
         
            +
              auth: subscription['keys']['auth'],
         
     | 
| 
      
 88 
     | 
    
         
            +
              vapid: {
         
     | 
| 
      
 89 
     | 
    
         
            +
                subject: "mailto:sender@example.com",
         
     | 
| 
      
 90 
     | 
    
         
            +
                public_key: ENV['VAPID_PUBLIC_KEY'],
         
     | 
| 
      
 91 
     | 
    
         
            +
                private_key: ENV['VAPID_PRIVATE_KEY']
         
     | 
| 
      
 92 
     | 
    
         
            +
              },
         
     | 
| 
      
 93 
     | 
    
         
            +
              ssl_timeout: 5, # optional value for Net::HTTP#ssl_timeout=
         
     | 
| 
      
 94 
     | 
    
         
            +
              open_timeout: 5, # optional value for Net::HTTP#open_timeout=
         
     | 
| 
      
 95 
     | 
    
         
            +
              read_timeout: 5 # optional value for Net::HTTP#read_timeout=
         
     | 
| 
      
 96 
     | 
    
         
            +
            )
         
     | 
| 
       182 
97 
     | 
    
         
             
            ```
         
     | 
| 
       183 
98 
     | 
    
         | 
| 
       184 
     | 
    
         
            -
            Note: the VAPID options should be omitted if the client-side subscription was
         
     | 
| 
       185 
     | 
    
         
            -
            generated without the `applicationServerKey` parameter described earlier. You
         
     | 
| 
       186 
     | 
    
         
            -
            would instead pass the GCM api key along with the api request as shown in the
         
     | 
| 
       187 
     | 
    
         
            -
            Usage section below.
         
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
99 
     | 
    
         
             
            ### Receiving the push event
         
     | 
| 
       190 
100 
     | 
    
         | 
| 
       191 
     | 
    
         
            -
            Your  
     | 
| 
      
 101 
     | 
    
         
            +
            Your `service-worker.js` script should respond to `'push'` events. One action it can take is to trigger desktop notifications by calling `showNotification` on the `registration` property.
         
     | 
| 
       192 
102 
     | 
    
         | 
| 
       193 
103 
     | 
    
         
             
            ```javascript
         
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
            //  
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
               
     | 
| 
       199 
     | 
    
         
            -
              let body = "We have received a push message";
         
     | 
| 
       200 
     | 
    
         
            -
              let tag = "push-simple-demo-notification-tag";
         
     | 
| 
       201 
     | 
    
         
            -
              let icon = '/assets/my-logo-120x120.png';
         
     | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
              event.waitUntil(
         
     | 
| 
       204 
     | 
    
         
            -
                self.registration.showNotification(title, { body, icon, tag })
         
     | 
| 
       205 
     | 
    
         
            -
              )
         
     | 
| 
      
 104 
     | 
    
         
            +
            self.addEventListener('push', (event) => {
         
     | 
| 
      
 105 
     | 
    
         
            +
              // Get the push message
         
     | 
| 
      
 106 
     | 
    
         
            +
              var message = event.data;
         
     | 
| 
      
 107 
     | 
    
         
            +
              // Display a notification
         
     | 
| 
      
 108 
     | 
    
         
            +
              event.waitUntil(self.registration.showNotification('Example'));
         
     | 
| 
       206 
109 
     | 
    
         
             
            });
         
     | 
| 
       207 
110 
     | 
    
         
             
            ```
         
     | 
| 
       208 
111 
     | 
    
         | 
| 
       209 
     | 
    
         
            -
            Before the notifications can be displayed, the user must grant permission for [notifications](https://developer.mozilla.org/en-US/docs/Web/API/notification) in a browser prompt 
     | 
| 
      
 112 
     | 
    
         
            +
            Before the notifications can be displayed, the user must grant permission for [notifications](https://developer.mozilla.org/en-US/docs/Web/API/notification) in a browser prompt. Use something like this in your JavaScript code:
         
     | 
| 
       210 
113 
     | 
    
         | 
| 
       211 
114 
     | 
    
         
             
            ```javascript
         
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
       213 
     | 
    
         
            -
             
     | 
| 
       214 
     | 
    
         
            -
            // Let's check if the browser supports notifications
         
     | 
| 
       215 
     | 
    
         
            -
            if (!("Notification" in window)) {
         
     | 
| 
       216 
     | 
    
         
            -
              console.error("This browser does not support desktop notification");
         
     | 
| 
       217 
     | 
    
         
            -
            }
         
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
            // Let's check whether notification permissions have already been granted
         
     | 
| 
       220 
     | 
    
         
            -
            else if (Notification.permission === "granted") {
         
     | 
| 
       221 
     | 
    
         
            -
              console.log("Permission to receive notifications has been granted");
         
     | 
| 
       222 
     | 
    
         
            -
            }
         
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
       224 
     | 
    
         
            -
            // Otherwise, we need to ask the user for permission
         
     | 
| 
       225 
     | 
    
         
            -
            else if (Notification.permission !== 'denied') {
         
     | 
| 
       226 
     | 
    
         
            -
              Notification.requestPermission(function (permission) {
         
     | 
| 
       227 
     | 
    
         
            -
                // If the user accepts, let's create a notification
         
     | 
| 
       228 
     | 
    
         
            -
                if (permission === "granted") {
         
     | 
| 
       229 
     | 
    
         
            -
                  console.log("Permission to receive notifications has been granted");
         
     | 
| 
       230 
     | 
    
         
            -
                }
         
     | 
| 
       231 
     | 
    
         
            -
              });
         
     | 
| 
       232 
     | 
    
         
            -
            }
         
     | 
| 
      
 115 
     | 
    
         
            +
            Notification.requestPermission();
         
     | 
| 
       233 
116 
     | 
    
         
             
            ```
         
     | 
| 
       234 
117 
     | 
    
         | 
| 
       235 
     | 
    
         
            -
            If everything worked, you should see a desktop notification triggered via web
         
     | 
| 
       236 
     | 
    
         
            -
            push. Yay!
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
            Note: if you're using Rails, check out [serviceworker-rails](https://github.com/rossta/serviceworker-rails), a gem that makes it easier to host serviceworker scripts and manifest.json files at canonical endpoints (i.e., non-digested URLs) while taking advantage of the asset pipeline.
         
     | 
| 
      
 118 
     | 
    
         
            +
            If everything worked, you should see a desktop notification triggered via web push. Yay!
         
     | 
| 
       239 
119 
     | 
    
         | 
| 
       240 
120 
     | 
    
         
             
            ## API
         
     | 
| 
       241 
121 
     | 
    
         | 
| 
         @@ -243,9 +123,9 @@ Note: if you're using Rails, check out [serviceworker-rails](https://github.com/ 
     | 
|
| 
       243 
123 
     | 
    
         | 
| 
       244 
124 
     | 
    
         
             
            ```ruby
         
     | 
| 
       245 
125 
     | 
    
         
             
            message = {
         
     | 
| 
       246 
     | 
    
         
            -
              title: " 
     | 
| 
       247 
     | 
    
         
            -
              body: " 
     | 
| 
       248 
     | 
    
         
            -
              icon: " 
     | 
| 
      
 126 
     | 
    
         
            +
              title: "Example",
         
     | 
| 
      
 127 
     | 
    
         
            +
              body: "Hello, world!",
         
     | 
| 
      
 128 
     | 
    
         
            +
              icon: "https://example.com/icon.png"
         
     | 
| 
       249 
129 
     | 
    
         
             
            }
         
     | 
| 
       250 
130 
     | 
    
         | 
| 
       251 
131 
     | 
    
         
             
            WebPush.payload_send(
         
     | 
| 
         @@ -304,53 +184,10 @@ WebPush.payload_send( 
     | 
|
| 
       304 
184 
     | 
    
         
             
            )
         
     | 
| 
       305 
185 
     | 
    
         
             
            ```
         
     | 
| 
       306 
186 
     | 
    
         | 
| 
       307 
     | 
    
         
            -
             
     | 
| 
       308 
     | 
    
         
            -
             
     | 
| 
       309 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       310 
     | 
    
         
            -
            WebPush.payload_send(
         
     | 
| 
       311 
     | 
    
         
            -
              endpoint: "https://fcm.googleapis.com/gcm/send/eah7hak....",
         
     | 
| 
       312 
     | 
    
         
            -
              message: "A message",
         
     | 
| 
       313 
     | 
    
         
            -
              p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
         
     | 
| 
       314 
     | 
    
         
            -
              auth: "aW1hcmthcmFpa3V6ZQ==",
         
     | 
| 
       315 
     | 
    
         
            -
              api_key: "<GCM API KEY>"
         
     | 
| 
       316 
     | 
    
         
            -
            )
         
     | 
| 
       317 
     | 
    
         
            -
            ```
         
     | 
| 
       318 
     | 
    
         
            -
             
     | 
| 
       319 
     | 
    
         
            -
            ### ServiceWorker sample
         
     | 
| 
       320 
     | 
    
         
            -
             
     | 
| 
       321 
     | 
    
         
            -
            see. https://github.com/zaru/web-push-sample
         
     | 
| 
       322 
     | 
    
         
            -
             
     | 
| 
       323 
     | 
    
         
            -
            p256dh and auth generate sample code.
         
     | 
| 
       324 
     | 
    
         
            -
             
     | 
| 
       325 
     | 
    
         
            -
            ```javascript
         
     | 
| 
       326 
     | 
    
         
            -
            navigator.serviceWorker.ready.then(function(sw) {
         
     | 
| 
       327 
     | 
    
         
            -
              Notification.requestPermission(function(permission) {
         
     | 
| 
       328 
     | 
    
         
            -
                if(permission !== 'denied') {
         
     | 
| 
       329 
     | 
    
         
            -
                  sw.pushManager.subscribe({userVisibleOnly: true}).then(function(s) {
         
     | 
| 
       330 
     | 
    
         
            -
                    var data = {
         
     | 
| 
       331 
     | 
    
         
            -
                      endpoint: s.endpoint,
         
     | 
| 
       332 
     | 
    
         
            -
                      p256dh: btoa(String.fromCharCode.apply(null, new Uint8Array(s.getKey('p256dh')))).replace(/\+/g, '-').replace(/\//g, '_'),
         
     | 
| 
       333 
     | 
    
         
            -
                      auth: btoa(String.fromCharCode.apply(null, new Uint8Array(s.getKey('auth')))).replace(/\+/g, '-').replace(/\//g, '_')
         
     | 
| 
       334 
     | 
    
         
            -
                    }
         
     | 
| 
       335 
     | 
    
         
            -
                    console.log(data);
         
     | 
| 
       336 
     | 
    
         
            -
                  });
         
     | 
| 
       337 
     | 
    
         
            -
                }
         
     | 
| 
       338 
     | 
    
         
            -
              });
         
     | 
| 
       339 
     | 
    
         
            -
            });
         
     | 
| 
       340 
     | 
    
         
            -
            ```
         
     | 
| 
      
 187 
     | 
    
         
            +
            ## Contributing
         
     | 
| 
       341 
188 
     | 
    
         | 
| 
       342 
     | 
    
         
            -
             
     | 
| 
      
 189 
     | 
    
         
            +
            Bug reports and pull requests are welcome on GitHub at https://github.com/pushpad/web-push.
         
     | 
| 
       343 
190 
     | 
    
         | 
| 
       344 
     | 
    
         
            -
             
     | 
| 
       345 
     | 
    
         
            -
            self.addEventListener("push", function(event) {
         
     | 
| 
       346 
     | 
    
         
            -
              var json = event.data.json();
         
     | 
| 
       347 
     | 
    
         
            -
              self.registration.showNotification(json.title, {
         
     | 
| 
       348 
     | 
    
         
            -
                body: json.body,
         
     | 
| 
       349 
     | 
    
         
            -
                icon: json.icon
         
     | 
| 
       350 
     | 
    
         
            -
              });
         
     | 
| 
       351 
     | 
    
         
            -
            });
         
     | 
| 
       352 
     | 
    
         
            -
            ```
         
     | 
| 
       353 
     | 
    
         
            -
             
     | 
| 
       354 
     | 
    
         
            -
            ## Contributing
         
     | 
| 
      
 191 
     | 
    
         
            +
            ## Credits
         
     | 
| 
       355 
192 
     | 
    
         | 
| 
       356 
     | 
    
         
            -
             
     | 
| 
      
 193 
     | 
    
         
            +
            This library is a fork of [zaru/webpush](https://github.com/zaru/webpush) actively maintained by [Pushpad](https://pushpad.xyz) with many improvements, bug fixes and frequent updates.
         
     | 
    
        data/lib/web_push/encryption.rb
    CHANGED
    
    | 
         @@ -4,7 +4,6 @@ module WebPush 
     | 
|
| 
       4 
4 
     | 
    
         
             
              module Encryption
         
     | 
| 
       5 
5 
     | 
    
         
             
                extend self
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
                # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
         
     | 
| 
       8 
7 
     | 
    
         
             
                def encrypt(message, p256dh, auth)
         
     | 
| 
       9 
8 
     | 
    
         
             
                  assert_arguments(message, p256dh, auth)
         
     | 
| 
       10 
9 
     | 
    
         | 
| 
         @@ -27,11 +26,11 @@ module WebPush 
     | 
|
| 
       27 
26 
     | 
    
         
             
                  content_encryption_key_info = "Content-Encoding: aes128gcm\0"
         
     | 
| 
       28 
27 
     | 
    
         
             
                  nonce_info = "Content-Encoding: nonce\0"
         
     | 
| 
       29 
28 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                  prk = HKDF.new(shared_secret, salt: client_auth_token, algorithm: 'SHA256', info: info). 
     | 
| 
      
 29 
     | 
    
         
            +
                  prk = HKDF.new(shared_secret, salt: client_auth_token, algorithm: 'SHA256', info: info).read(32)
         
     | 
| 
       31 
30 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                  content_encryption_key = HKDF.new(prk, salt: salt, info: content_encryption_key_info). 
     | 
| 
      
 31 
     | 
    
         
            +
                  content_encryption_key = HKDF.new(prk, salt: salt, info: content_encryption_key_info).read(16)
         
     | 
| 
       33 
32 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                  nonce = HKDF.new(prk, salt: salt, info: nonce_info). 
     | 
| 
      
 33 
     | 
    
         
            +
                  nonce = HKDF.new(prk, salt: salt, info: nonce_info).read(12)
         
     | 
| 
       35 
34 
     | 
    
         | 
| 
       36 
35 
     | 
    
         
             
                  ciphertext = encrypt_payload(message, content_encryption_key, nonce)
         
     | 
| 
       37 
36 
     | 
    
         | 
| 
         @@ -43,7 +42,6 @@ module WebPush 
     | 
|
| 
       43 
42 
     | 
    
         | 
| 
       44 
43 
     | 
    
         
             
                  aes128gcmheader + ciphertext
         
     | 
| 
       45 
44 
     | 
    
         
             
                end
         
     | 
| 
       46 
     | 
    
         
            -
                # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
         
     | 
| 
       47 
45 
     | 
    
         | 
| 
       48 
46 
     | 
    
         
             
                private
         
     | 
| 
       49 
47 
     | 
    
         | 
    
        data/lib/web_push/request.rb
    CHANGED
    
    | 
         @@ -1,25 +1,16 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require 'uri'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'jwt'
         
     | 
| 
       5 
     | 
    
         
            -
            require 'base64'
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
3 
     | 
    
         
             
            module WebPush
         
     | 
| 
       8 
     | 
    
         
            -
              # It is temporary URL until supported by the GCM server.
         
     | 
| 
       9 
     | 
    
         
            -
              GCM_URL = 'https://android.googleapis.com/gcm/send'.freeze
         
     | 
| 
       10 
     | 
    
         
            -
              TEMP_GCM_URL = 'https://fcm.googleapis.com/fcm'.freeze
         
     | 
| 
       11 
4 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
              # rubocop:disable Metrics/ClassLength
         
     | 
| 
       13 
5 
     | 
    
         
             
              class Request
         
     | 
| 
       14 
6 
     | 
    
         
             
                def initialize(message: '', subscription:, vapid:, **options)
         
     | 
| 
       15 
7 
     | 
    
         
             
                  endpoint = subscription.fetch(:endpoint)
         
     | 
| 
       16 
     | 
    
         
            -
                  @endpoint = endpoint 
     | 
| 
      
 8 
     | 
    
         
            +
                  @endpoint = endpoint
         
     | 
| 
       17 
9 
     | 
    
         
             
                  @payload = build_payload(message, subscription)
         
     | 
| 
       18 
10 
     | 
    
         
             
                  @vapid_options = vapid
         
     | 
| 
       19 
11 
     | 
    
         
             
                  @options = default_options.merge(options)
         
     | 
| 
       20 
12 
     | 
    
         
             
                end
         
     | 
| 
       21 
13 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                # rubocop:disable Metrics/AbcSize
         
     | 
| 
       23 
14 
     | 
    
         
             
                def perform
         
     | 
| 
       24 
15 
     | 
    
         
             
                  http = Net::HTTP.new(uri.host, uri.port, *proxy_options)
         
     | 
| 
       25 
16 
     | 
    
         
             
                  http.use_ssl = true
         
     | 
| 
         @@ -35,7 +26,6 @@ module WebPush 
     | 
|
| 
       35 
26 
     | 
    
         | 
| 
       36 
27 
     | 
    
         
             
                  resp
         
     | 
| 
       37 
28 
     | 
    
         
             
                end
         
     | 
| 
       38 
     | 
    
         
            -
                # rubocop:enable Metrics/AbcSize
         
     | 
| 
       39 
29 
     | 
    
         | 
| 
       40 
30 
     | 
    
         
             
                def proxy_options
         
     | 
| 
       41 
31 
     | 
    
         
             
                  return [] unless @options[:proxy]
         
     | 
| 
         @@ -45,7 +35,6 @@ module WebPush 
     | 
|
| 
       45 
35 
     | 
    
         
             
                  [proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password]
         
     | 
| 
       46 
36 
     | 
    
         
             
                end
         
     | 
| 
       47 
37 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                # rubocop:disable Metrics/MethodLength
         
     | 
| 
       49 
38 
     | 
    
         
             
                def headers
         
     | 
| 
       50 
39 
     | 
    
         
             
                  headers = {}
         
     | 
| 
       51 
40 
     | 
    
         
             
                  headers['Content-Type'] = 'application/octet-stream'
         
     | 
| 
         @@ -57,24 +46,18 @@ module WebPush 
     | 
|
| 
       57 
46 
     | 
    
         
             
                    headers["Content-Length"] = @payload.length.to_s
         
     | 
| 
       58 
47 
     | 
    
         
             
                  end
         
     | 
| 
       59 
48 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                  if  
     | 
| 
       61 
     | 
    
         
            -
                    headers['Authorization'] = "key=#{api_key}"
         
     | 
| 
       62 
     | 
    
         
            -
                  elsif vapid?
         
     | 
| 
      
 49 
     | 
    
         
            +
                  if vapid?
         
     | 
| 
       63 
50 
     | 
    
         
             
                    headers["Authorization"] = build_vapid_header
         
     | 
| 
       64 
51 
     | 
    
         
             
                  end
         
     | 
| 
       65 
52 
     | 
    
         | 
| 
       66 
53 
     | 
    
         
             
                  headers
         
     | 
| 
       67 
54 
     | 
    
         
             
                end
         
     | 
| 
       68 
     | 
    
         
            -
                # rubocop:enable Metrics/MethodLength
         
     | 
| 
       69 
55 
     | 
    
         | 
| 
       70 
56 
     | 
    
         
             
                def build_vapid_header
         
     | 
| 
       71 
     | 
    
         
            -
                  # https://tools.ietf.org/id/draft-ietf-webpush-vapid-03.html
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
57 
     | 
    
         
             
                  vapid_key = vapid_pem ? VapidKey.from_pem(vapid_pem) : VapidKey.from_keys(vapid_public_key, vapid_private_key)
         
     | 
| 
       74 
58 
     | 
    
         
             
                  jwt = JWT.encode(jwt_payload, vapid_key.curve, 'ES256', jwt_header_fields)
         
     | 
| 
       75 
59 
     | 
    
         
             
                  p256ecdsa = vapid_key.public_key_for_push_header
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                   "vapid t=#{jwt},k=#{p256ecdsa}"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  "vapid t=#{jwt},k=#{p256ecdsa}"
         
     | 
| 
       78 
61 
     | 
    
         
             
                end
         
     | 
| 
       79 
62 
     | 
    
         | 
| 
       80 
63 
     | 
    
         
             
                def body
         
     | 
| 
         @@ -112,11 +95,11 @@ module WebPush 
     | 
|
| 
       112 
95 
     | 
    
         
             
                end
         
     | 
| 
       113 
96 
     | 
    
         | 
| 
       114 
97 
     | 
    
         
             
                def expiration
         
     | 
| 
       115 
     | 
    
         
            -
                  @vapid_options.fetch(:expiration,  
     | 
| 
      
 98 
     | 
    
         
            +
                  @vapid_options.fetch(:expiration, 12 * 60 * 60)
         
     | 
| 
       116 
99 
     | 
    
         
             
                end
         
     | 
| 
       117 
100 
     | 
    
         | 
| 
       118 
101 
     | 
    
         
             
                def subject
         
     | 
| 
       119 
     | 
    
         
            -
                  @vapid_options.fetch(:subject, 'sender@example.com')
         
     | 
| 
      
 102 
     | 
    
         
            +
                  @vapid_options.fetch(:subject, 'mailto:sender@example.com')
         
     | 
| 
       120 
103 
     | 
    
         
             
                end
         
     | 
| 
       121 
104 
     | 
    
         | 
| 
       122 
105 
     | 
    
         
             
                def vapid_public_key
         
     | 
| 
         @@ -148,14 +131,6 @@ module WebPush 
     | 
|
| 
       148 
131 
     | 
    
         
             
                  Encryption.encrypt(message, p256dh, auth)
         
     | 
| 
       149 
132 
     | 
    
         
             
                end
         
     | 
| 
       150 
133 
     | 
    
         | 
| 
       151 
     | 
    
         
            -
                def api_key
         
     | 
| 
       152 
     | 
    
         
            -
                  @options.fetch(:api_key, nil)
         
     | 
| 
       153 
     | 
    
         
            -
                end
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
                def api_key?
         
     | 
| 
       156 
     | 
    
         
            -
                  !(api_key.nil? || api_key.empty?) && @endpoint =~ %r{\Ahttps://(android|gcm-http|fcm)\.googleapis\.com}
         
     | 
| 
       157 
     | 
    
         
            -
                end
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
134 
     | 
    
         
             
                def vapid?
         
     | 
| 
       160 
135 
     | 
    
         
             
                  @vapid_options.any?
         
     | 
| 
       161 
136 
     | 
    
         
             
                end
         
     | 
| 
         @@ -164,7 +139,6 @@ module WebPush 
     | 
|
| 
       164 
139 
     | 
    
         
             
                  WebPush.encode64(bin).delete('=')
         
     | 
| 
       165 
140 
     | 
    
         
             
                end
         
     | 
| 
       166 
141 
     | 
    
         | 
| 
       167 
     | 
    
         
            -
                # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Style/GuardClause
         
     | 
| 
       168 
142 
     | 
    
         
             
                def verify_response(resp)
         
     | 
| 
       169 
143 
     | 
    
         
             
                  if resp.is_a?(Net::HTTPGone) # 410
         
     | 
| 
       170 
144 
     | 
    
         
             
                    raise ExpiredSubscription.new(resp, uri.host)
         
     | 
| 
         @@ -183,7 +157,5 @@ module WebPush 
     | 
|
| 
       183 
157 
     | 
    
         
             
                    raise ResponseError.new(resp, uri.host)
         
     | 
| 
       184 
158 
     | 
    
         
             
                  end
         
     | 
| 
       185 
159 
     | 
    
         
             
                end
         
     | 
| 
       186 
     | 
    
         
            -
                # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Style/GuardClause
         
     | 
| 
       187 
160 
     | 
    
         
             
              end
         
     | 
| 
       188 
     | 
    
         
            -
              # rubocop:enable Metrics/ClassLength
         
     | 
| 
       189 
161 
     | 
    
         
             
            end
         
     | 
    
        data/lib/web_push/vapid_key.rb
    CHANGED
    
    | 
         @@ -78,10 +78,15 @@ module WebPush 
     | 
|
| 
       78 
78 
     | 
    
         
             
                alias to_hash to_h
         
     | 
| 
       79 
79 
     | 
    
         | 
| 
       80 
80 
     | 
    
         
             
                def to_pem
         
     | 
| 
       81 
     | 
    
         
            -
                   
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
      
 81 
     | 
    
         
            +
                  private_key_to_pem + public_key_to_pem
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                def private_key_to_pem
         
     | 
| 
      
 85 
     | 
    
         
            +
                  curve.to_pem
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
       83 
87 
     | 
    
         | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
      
 88 
     | 
    
         
            +
                def public_key_to_pem
         
     | 
| 
      
 89 
     | 
    
         
            +
                  curve.public_to_pem
         
     | 
| 
       85 
90 
     | 
    
         
             
                end
         
     | 
| 
       86 
91 
     | 
    
         | 
| 
       87 
92 
     | 
    
         
             
                def inspect
         
     | 
    
        data/lib/web_push/version.rb
    CHANGED
    
    
    
        data/lib/web_push.rb
    CHANGED
    
    | 
         @@ -3,6 +3,8 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require 'openssl'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'base64'
         
     | 
| 
       5 
5 
     | 
    
         
             
            require 'hkdf'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'jwt'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'uri'
         
     | 
| 
       6 
8 
     | 
    
         
             
            require 'net/http'
         
     | 
| 
       7 
9 
     | 
    
         
             
            require 'json'
         
     | 
| 
       8 
10 
     | 
    
         | 
| 
         @@ -11,7 +13,6 @@ require 'web_push/errors' 
     | 
|
| 
       11 
13 
     | 
    
         
             
            require 'web_push/vapid_key'
         
     | 
| 
       12 
14 
     | 
    
         
             
            require 'web_push/encryption'
         
     | 
| 
       13 
15 
     | 
    
         
             
            require 'web_push/request'
         
     | 
| 
       14 
     | 
    
         
            -
            require 'web_push/railtie' if defined?(Rails)
         
     | 
| 
       15 
16 
     | 
    
         | 
| 
       16 
17 
     | 
    
         
             
            # Push API implementation
         
     | 
| 
       17 
18 
     | 
    
         
             
            #
         
     | 
| 
         @@ -34,7 +35,6 @@ module WebPush 
     | 
|
| 
       34 
35 
     | 
    
         
             
                # @param options [Hash<Symbol,String>] additional options for the notification
         
     | 
| 
       35 
36 
     | 
    
         
             
                # @option options [#to_s] :ttl Time-to-live in seconds
         
     | 
| 
       36 
37 
     | 
    
         
             
                # @option options [#to_s] :urgency Urgency can be very-low, low, normal, high
         
     | 
| 
       37 
     | 
    
         
            -
                # rubocop:disable Metrics/ParameterLists
         
     | 
| 
       38 
38 
     | 
    
         
             
                def payload_send(message: '', endpoint:, p256dh: '', auth: '', vapid: {}, **options)
         
     | 
| 
       39 
39 
     | 
    
         
             
                  WebPush::Request.new(
         
     | 
| 
       40 
40 
     | 
    
         
             
                    message: message,
         
     | 
| 
         @@ -43,7 +43,6 @@ module WebPush 
     | 
|
| 
       43 
43 
     | 
    
         
             
                    **options
         
     | 
| 
       44 
44 
     | 
    
         
             
                  ).perform
         
     | 
| 
       45 
45 
     | 
    
         
             
                end
         
     | 
| 
       46 
     | 
    
         
            -
                # rubocop:enable Metrics/ParameterLists
         
     | 
| 
       47 
46 
     | 
    
         | 
| 
       48 
47 
     | 
    
         
             
                # Generate a VapidKey instance to obtain base64 encoded public and private keys
         
     | 
| 
       49 
48 
     | 
    
         
             
                # suitable for VAPID protocol JSON web token signing
         
     | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    
| 
         @@ -67,10 +67,10 @@ describe WebPush::Encryption do 
     | 
|
| 
       67 
67 
     | 
    
         
             
                  content_encryption_key_info = "Content-Encoding: aes128gcm\0"
         
     | 
| 
       68 
68 
     | 
    
         
             
                  nonce_info = "Content-Encoding: nonce\0"
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
       70 
     | 
    
         
            -
                  prk = HKDF.new(shared_secret, salt: client_auth_token, algorithm: 'SHA256', info: info). 
     | 
| 
      
 70 
     | 
    
         
            +
                  prk = HKDF.new(shared_secret, salt: client_auth_token, algorithm: 'SHA256', info: info).read(32)
         
     | 
| 
       71 
71 
     | 
    
         | 
| 
       72 
     | 
    
         
            -
                  content_encryption_key = HKDF.new(prk, salt: salt, info: content_encryption_key_info). 
     | 
| 
       73 
     | 
    
         
            -
                  nonce = HKDF.new(prk, salt: salt, info: nonce_info). 
     | 
| 
      
 72 
     | 
    
         
            +
                  content_encryption_key = HKDF.new(prk, salt: salt, info: content_encryption_key_info).read(16)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  nonce = HKDF.new(prk, salt: salt, info: nonce_info).read(12)
         
     | 
| 
       74 
74 
     | 
    
         | 
| 
       75 
75 
     | 
    
         
             
                  decrypt_ciphertext(ciphertext, content_encryption_key, nonce)
         
     | 
| 
       76 
76 
     | 
    
         
             
                end
         
     | 
| 
         @@ -18,51 +18,6 @@ describe WebPush::Request do 
     | 
|
| 
       18 
18 
     | 
    
         
             
                  end
         
     | 
| 
       19 
19 
     | 
    
         
             
                end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                describe 'from :api_key' do
         
     | 
| 
       22 
     | 
    
         
            -
                  def build_request_with_api_key(endpoint, options = {})
         
     | 
| 
       23 
     | 
    
         
            -
                    subscription = {
         
     | 
| 
       24 
     | 
    
         
            -
                      endpoint: endpoint,
         
     | 
| 
       25 
     | 
    
         
            -
                      keys: {
         
     | 
| 
       26 
     | 
    
         
            -
                        p256dh: 'p256dh',
         
     | 
| 
       27 
     | 
    
         
            -
                        auth: 'auth'
         
     | 
| 
       28 
     | 
    
         
            -
                      }
         
     | 
| 
       29 
     | 
    
         
            -
                    }
         
     | 
| 
       30 
     | 
    
         
            -
                    WebPush::Request.new(message: '', subscription: subscription, vapid: {}, **options)
         
     | 
| 
       31 
     | 
    
         
            -
                  end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                  it 'inserts Authorization header when api_key present, and endpoint is for Chrome\'s non-standards-compliant GCM endpoints' do
         
     | 
| 
       34 
     | 
    
         
            -
                    request = build_request_with_api_key('https://gcm-http.googleapis.com/gcm/xyz', api_key: 'api_key')
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                    expect(request.headers['Authorization']).to eq('key=api_key')
         
     | 
| 
       37 
     | 
    
         
            -
                  end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                  it 'insert Authorization header for Chrome\'s new standards-compliant endpoints, even if api_key is present' do
         
     | 
| 
       40 
     | 
    
         
            -
                    request = build_request_with_api_key('https://fcm.googleapis.com/fcm/send/ABCD1234', api_key: 'api_key')
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                    expect(request.headers['Authorization']).to eq('key=api_key')
         
     | 
| 
       43 
     | 
    
         
            -
                  end
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                  it 'does not insert Authorization header when endpoint is not for Chrome, even if api_key is present' do
         
     | 
| 
       46 
     | 
    
         
            -
                    request = build_request_with_api_key('https://some.random.endpoint.com/xyz', api_key: 'api_key')
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                    expect(request.headers['Authorization']).to be_nil
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                  it 'does not insert Authorization header when api_key blank' do
         
     | 
| 
       52 
     | 
    
         
            -
                    request = build_request_with_api_key('endpoint', api_key: nil)
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                    expect(request.headers['Authorization']).to be_nil
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                    request = build_request_with_api_key('endpoint', api_key: '')
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                    expect(request.headers['Authorization']).to be_nil
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                    request = build_request_with_api_key('endpoint')
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                    expect(request.headers['Authorization']).to be_nil
         
     | 
| 
       63 
     | 
    
         
            -
                  end
         
     | 
| 
       64 
     | 
    
         
            -
                end
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
21 
     | 
    
         
             
                describe 'from :ttl' do
         
     | 
| 
       67 
22 
     | 
    
         
             
                  it 'can override Ttl with :ttl option with string' do
         
     | 
| 
       68 
23 
     | 
    
         
             
                    request = build_request(ttl: '300')
         
     | 
| 
         @@ -91,7 +46,7 @@ describe WebPush::Request do 
     | 
|
| 
       91 
46 
     | 
    
         
             
                  time = Time.at(1_476_150_897)
         
     | 
| 
       92 
47 
     | 
    
         
             
                  jwt_payload = {
         
     | 
| 
       93 
48 
     | 
    
         
             
                    aud: 'https://fcm.googleapis.com',
         
     | 
| 
       94 
     | 
    
         
            -
                    exp: time.to_i +  
     | 
| 
      
 49 
     | 
    
         
            +
                    exp: time.to_i + 12 * 60 * 60,
         
     | 
| 
       95 
50 
     | 
    
         
             
                    sub: 'mailto:sender@example.com'
         
     | 
| 
       96 
51 
     | 
    
         
             
                  }
         
     | 
| 
       97 
52 
     | 
    
         
             
                  jwt_header_fields = { "typ": "JWT", "alg": "ES256" }
         
     | 
| 
         @@ -43,6 +43,35 @@ describe WebPush::VapidKey do 
     | 
|
| 
       43 
43 
     | 
    
         
             
                expect(pem).to include('-----BEGIN PUBLIC KEY-----')
         
     | 
| 
       44 
44 
     | 
    
         
             
              end
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
      
 46 
     | 
    
         
            +
              it 'returns the correct public and private keys in pem format' do
         
     | 
| 
      
 47 
     | 
    
         
            +
                public_key_base64 = 'BMA-wciFTkEq2waVGB2hg8cSyiRiMcsIvIYQb3LkLOmBheh3YC6NB2GtE9t6YgaXt428rp7bC9JjuPtAY9AQaR8='
         
     | 
| 
      
 48 
     | 
    
         
            +
                private_key_base64 = '4MwLvN1Cpxe43AV9fa4BiS-SPp51gWlhv9c6bb_XSJ4='
         
     | 
| 
      
 49 
     | 
    
         
            +
                key = WebPush::VapidKey.from_keys(public_key_base64, private_key_base64)
         
     | 
| 
      
 50 
     | 
    
         
            +
                pem = key.to_pem
         
     | 
| 
      
 51 
     | 
    
         
            +
                expected_pem = <<~PEM
         
     | 
| 
      
 52 
     | 
    
         
            +
                  -----BEGIN EC PRIVATE KEY-----
         
     | 
| 
      
 53 
     | 
    
         
            +
                  MHcCAQEEIODMC7zdQqcXuNwFfX2uAYkvkj6edYFpYb/XOm2/10ieoAoGCCqGSM49
         
     | 
| 
      
 54 
     | 
    
         
            +
                  AwEHoUQDQgAEwD7ByIVOQSrbBpUYHaGDxxLKJGIxywi8hhBvcuQs6YGF6HdgLo0H
         
     | 
| 
      
 55 
     | 
    
         
            +
                  Ya0T23piBpe3jbyuntsL0mO4+0Bj0BBpHw==
         
     | 
| 
      
 56 
     | 
    
         
            +
                  -----END EC PRIVATE KEY-----
         
     | 
| 
      
 57 
     | 
    
         
            +
                  -----BEGIN PUBLIC KEY-----
         
     | 
| 
      
 58 
     | 
    
         
            +
                  MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwD7ByIVOQSrbBpUYHaGDxxLKJGIx
         
     | 
| 
      
 59 
     | 
    
         
            +
                  ywi8hhBvcuQs6YGF6HdgLo0HYa0T23piBpe3jbyuntsL0mO4+0Bj0BBpHw==
         
     | 
| 
      
 60 
     | 
    
         
            +
                  -----END PUBLIC KEY-----
         
     | 
| 
      
 61 
     | 
    
         
            +
                PEM
         
     | 
| 
      
 62 
     | 
    
         
            +
                expect(pem).to eq(expected_pem)
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
              it 'can return the private key in pem format' do
         
     | 
| 
      
 66 
     | 
    
         
            +
                pem = WebPush::VapidKey.new.private_key_to_pem
         
     | 
| 
      
 67 
     | 
    
         
            +
                expect(pem).to include('-----BEGIN EC PRIVATE KEY-----')
         
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
              it 'can return the public key in pem format' do
         
     | 
| 
      
 71 
     | 
    
         
            +
                pem = WebPush::VapidKey.new.public_key_to_pem
         
     | 
| 
      
 72 
     | 
    
         
            +
                expect(pem).to include('-----BEGIN PUBLIC KEY-----')
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
       46 
75 
     | 
    
         
             
              it 'imports pem of public and private keys' do
         
     | 
| 
       47 
76 
     | 
    
         
             
                pem = WebPush::VapidKey.new.to_pem
         
     | 
| 
       48 
77 
     | 
    
         
             
                key = WebPush::VapidKey.from_pem pem
         
     | 
    
        data/spec/web_push_spec.rb
    CHANGED
    
    | 
         @@ -194,8 +194,8 @@ describe WebPush do 
     | 
|
| 
       194 
194 
     | 
    
         
             
                include_examples 'request headers with VAPID'
         
     | 
| 
       195 
195 
     | 
    
         
             
              end
         
     | 
| 
       196 
196 
     | 
    
         | 
| 
       197 
     | 
    
         
            -
              context 'chrome  
     | 
| 
       198 
     | 
    
         
            -
                let(:endpoint) { 'https:// 
     | 
| 
      
 197 
     | 
    
         
            +
              context 'chrome endpoint: request headers without VAPID' do
         
     | 
| 
      
 198 
     | 
    
         
            +
                let(:endpoint) { 'https://fcm.googleapis.com/fcm/subscription-id' }
         
     | 
| 
       199 
199 
     | 
    
         
             
                let(:expected_endpoint) { 'https://fcm.googleapis.com/fcm/subscription-id' }
         
     | 
| 
       200 
200 
     | 
    
         | 
| 
       201 
201 
     | 
    
         
             
                let(:message) { JSON.generate(body: 'body') }
         
     | 
| 
         @@ -221,7 +221,7 @@ describe WebPush do 
     | 
|
| 
       221 
221 
     | 
    
         
             
                  allow(WebPush::Encryption).to receive(:encrypt).and_return(payload)
         
     | 
| 
       222 
222 
     | 
    
         
             
                end
         
     | 
| 
       223 
223 
     | 
    
         | 
| 
       224 
     | 
    
         
            -
                subject { WebPush.payload_send(message: message, endpoint: endpoint, p256dh: p256dh, auth: auth 
     | 
| 
      
 224 
     | 
    
         
            +
                subject { WebPush.payload_send(message: message, endpoint: endpoint, p256dh: p256dh, auth: auth) }
         
     | 
| 
       225 
225 
     | 
    
         | 
| 
       226 
226 
     | 
    
         
             
                it 'calls the relevant service with the correct headers' do
         
     | 
| 
       227 
227 
     | 
    
         
             
                  expect(WebPush::Encryption).to receive(:encrypt).and_return(payload)
         
     | 
| 
         @@ -247,7 +247,7 @@ describe WebPush do 
     | 
|
| 
       247 
247 
     | 
    
         
             
                    .with(body: nil, headers: expected_headers)
         
     | 
| 
       248 
248 
     | 
    
         
             
                    .to_return(status: 201, body: '', headers: {})
         
     | 
| 
       249 
249 
     | 
    
         | 
| 
       250 
     | 
    
         
            -
                  WebPush.payload_send(endpoint: endpoint 
     | 
| 
      
 250 
     | 
    
         
            +
                  WebPush.payload_send(endpoint: endpoint)
         
     | 
| 
       251 
251 
     | 
    
         
             
                end
         
     | 
| 
       252 
252 
     | 
    
         
             
              end
         
     | 
| 
       253 
253 
     | 
    
         
             
            end
         
     | 
    
        data/web-push.gemspec
    CHANGED
    
    | 
         @@ -3,6 +3,7 @@ require_relative 'lib/web_push/version' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            Gem::Specification.new do |spec|
         
     | 
| 
       4 
4 
     | 
    
         
             
              spec.name = 'web-push'
         
     | 
| 
       5 
5 
     | 
    
         
             
              spec.version = WebPush::VERSION
         
     | 
| 
      
 6 
     | 
    
         
            +
              spec.license = 'MIT'
         
     | 
| 
       6 
7 
     | 
    
         
             
              spec.authors = ['zaru', 'collimarco']
         
     | 
| 
       7 
8 
     | 
    
         
             
              spec.email = ['support@pushpad.xyz']
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
         @@ -11,15 +12,13 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       11 
12 
     | 
    
         | 
| 
       12 
13 
     | 
    
         
             
              spec.files = `git ls-files`.split("\n")
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
              spec.required_ruby_version = '>=  
     | 
| 
      
 15 
     | 
    
         
            +
              spec.required_ruby_version = '>= 3.0'
         
     | 
| 
       15 
16 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
              spec.add_dependency 'hkdf', '~> 0 
     | 
| 
      
 17 
     | 
    
         
            +
              spec.add_dependency 'hkdf', '~> 1.0'
         
     | 
| 
       17 
18 
     | 
    
         
             
              spec.add_dependency 'jwt', '~> 2.0'
         
     | 
| 
      
 19 
     | 
    
         
            +
              spec.add_dependency 'openssl', '~> 2.2'
         
     | 
| 
       18 
20 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
              spec.add_development_dependency 'bundler', '>= 1.17.3'
         
     | 
| 
       20 
     | 
    
         
            -
              spec.add_development_dependency 'pry'
         
     | 
| 
       21 
     | 
    
         
            -
              spec.add_development_dependency 'rake', '>= 10.0'
         
     | 
| 
       22 
21 
     | 
    
         
             
              spec.add_development_dependency 'rspec', '~> 3.0'
         
     | 
| 
       23 
     | 
    
         
            -
              spec.add_development_dependency 'simplecov'
         
     | 
| 
      
 22 
     | 
    
         
            +
              spec.add_development_dependency 'simplecov', '~> 0.0'
         
     | 
| 
       24 
23 
     | 
    
         
             
              spec.add_development_dependency 'webmock', '~> 3.0'
         
     | 
| 
       25 
24 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: web-push
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version:  
     | 
| 
      
 4 
     | 
    
         
            +
              version: 2.0.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - zaru
         
     | 
| 
         @@ -9,7 +9,7 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire:
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date: 2022-11- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2022-11-27 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies:
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       15 
15 
     | 
    
         
             
              name: hkdf
         
     | 
| 
         @@ -17,14 +17,14 @@ dependencies: 
     | 
|
| 
       17 
17 
     | 
    
         
             
                requirements:
         
     | 
| 
       18 
18 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       19 
19 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       20 
     | 
    
         
            -
                    version: '0 
     | 
| 
      
 20 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
       21 
21 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       22 
22 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       23 
23 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       24 
24 
     | 
    
         
             
                requirements:
         
     | 
| 
       25 
25 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       26 
26 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       27 
     | 
    
         
            -
                    version: '0 
     | 
| 
      
 27 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
       28 
28 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       29 
29 
     | 
    
         
             
              name: jwt
         
     | 
| 
       30 
30 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -40,47 +40,19 @@ dependencies: 
     | 
|
| 
       40 
40 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       41 
41 
     | 
    
         
             
                    version: '2.0'
         
     | 
| 
       42 
42 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       43 
     | 
    
         
            -
              name:  
     | 
| 
      
 43 
     | 
    
         
            +
              name: openssl
         
     | 
| 
       44 
44 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       45 
45 
     | 
    
         
             
                requirements:
         
     | 
| 
       46 
     | 
    
         
            -
                - - " 
     | 
| 
       47 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       48 
     | 
    
         
            -
                    version: 1.17.3
         
     | 
| 
       49 
     | 
    
         
            -
              type: :development
         
     | 
| 
       50 
     | 
    
         
            -
              prerelease: false
         
     | 
| 
       51 
     | 
    
         
            -
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       52 
     | 
    
         
            -
                requirements:
         
     | 
| 
       53 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       54 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       55 
     | 
    
         
            -
                    version: 1.17.3
         
     | 
| 
       56 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency
         
     | 
| 
       57 
     | 
    
         
            -
              name: pry
         
     | 
| 
       58 
     | 
    
         
            -
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       59 
     | 
    
         
            -
                requirements:
         
     | 
| 
       60 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       61 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       62 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
       63 
     | 
    
         
            -
              type: :development
         
     | 
| 
       64 
     | 
    
         
            -
              prerelease: false
         
     | 
| 
       65 
     | 
    
         
            -
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       66 
     | 
    
         
            -
                requirements:
         
     | 
| 
       67 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       68 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       69 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
       70 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency
         
     | 
| 
       71 
     | 
    
         
            -
              name: rake
         
     | 
| 
       72 
     | 
    
         
            -
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       73 
     | 
    
         
            -
                requirements:
         
     | 
| 
       74 
     | 
    
         
            -
                - - ">="
         
     | 
| 
      
 46 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
       75 
47 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       76 
     | 
    
         
            -
                    version: ' 
     | 
| 
       77 
     | 
    
         
            -
              type: : 
     | 
| 
      
 48 
     | 
    
         
            +
                    version: '2.2'
         
     | 
| 
      
 49 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
       78 
50 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       79 
51 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       80 
52 
     | 
    
         
             
                requirements:
         
     | 
| 
       81 
     | 
    
         
            -
                - - " 
     | 
| 
      
 53 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
       82 
54 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       83 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 55 
     | 
    
         
            +
                    version: '2.2'
         
     | 
| 
       84 
56 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       85 
57 
     | 
    
         
             
              name: rspec
         
     | 
| 
       86 
58 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -99,16 +71,16 @@ dependencies: 
     | 
|
| 
       99 
71 
     | 
    
         
             
              name: simplecov
         
     | 
| 
       100 
72 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       101 
73 
     | 
    
         
             
                requirements:
         
     | 
| 
       102 
     | 
    
         
            -
                - - " 
     | 
| 
      
 74 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
       103 
75 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       104 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
      
 76 
     | 
    
         
            +
                    version: '0.0'
         
     | 
| 
       105 
77 
     | 
    
         
             
              type: :development
         
     | 
| 
       106 
78 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       107 
79 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       108 
80 
     | 
    
         
             
                requirements:
         
     | 
| 
       109 
     | 
    
         
            -
                - - " 
     | 
| 
      
 81 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
       110 
82 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       111 
     | 
    
         
            -
                    version: '0'
         
     | 
| 
      
 83 
     | 
    
         
            +
                    version: '0.0'
         
     | 
| 
       112 
84 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       113 
85 
     | 
    
         
             
              name: webmock
         
     | 
| 
       114 
86 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -130,25 +102,15 @@ executables: [] 
     | 
|
| 
       130 
102 
     | 
    
         
             
            extensions: []
         
     | 
| 
       131 
103 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       132 
104 
     | 
    
         
             
            files:
         
     | 
| 
      
 105 
     | 
    
         
            +
            - ".github/workflows/ci.yml"
         
     | 
| 
       133 
106 
     | 
    
         
             
            - ".gitignore"
         
     | 
| 
       134 
     | 
    
         
            -
            - ".rspec"
         
     | 
| 
       135 
     | 
    
         
            -
            - ".rubocop.yml"
         
     | 
| 
       136 
     | 
    
         
            -
            - ".travis.yml"
         
     | 
| 
       137 
     | 
    
         
            -
            - CHANGELOG.md
         
     | 
| 
       138 
107 
     | 
    
         
             
            - Gemfile
         
     | 
| 
       139 
108 
     | 
    
         
             
            - LICENSE
         
     | 
| 
       140 
109 
     | 
    
         
             
            - README.md
         
     | 
| 
       141 
     | 
    
         
            -
            - Rakefile
         
     | 
| 
       142 
     | 
    
         
            -
            - bin/console
         
     | 
| 
       143 
     | 
    
         
            -
            - bin/rake
         
     | 
| 
       144 
     | 
    
         
            -
            - bin/rspec
         
     | 
| 
       145 
     | 
    
         
            -
            - bin/setup
         
     | 
| 
       146 
     | 
    
         
            -
            - lib/tasks/web_push.rake
         
     | 
| 
       147 
110 
     | 
    
         
             
            - lib/web-push.rb
         
     | 
| 
       148 
111 
     | 
    
         
             
            - lib/web_push.rb
         
     | 
| 
       149 
112 
     | 
    
         
             
            - lib/web_push/encryption.rb
         
     | 
| 
       150 
113 
     | 
    
         
             
            - lib/web_push/errors.rb
         
     | 
| 
       151 
     | 
    
         
            -
            - lib/web_push/railtie.rb
         
     | 
| 
       152 
114 
     | 
    
         
             
            - lib/web_push/request.rb
         
     | 
| 
       153 
115 
     | 
    
         
             
            - lib/web_push/vapid_key.rb
         
     | 
| 
       154 
116 
     | 
    
         
             
            - lib/web_push/version.rb
         
     | 
| 
         @@ -159,7 +121,8 @@ files: 
     | 
|
| 
       159 
121 
     | 
    
         
             
            - spec/web_push_spec.rb
         
     | 
| 
       160 
122 
     | 
    
         
             
            - web-push.gemspec
         
     | 
| 
       161 
123 
     | 
    
         
             
            homepage: https://github.com/pushpad/web-push
         
     | 
| 
       162 
     | 
    
         
            -
            licenses: 
     | 
| 
      
 124 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 125 
     | 
    
         
            +
            - MIT
         
     | 
| 
       163 
126 
     | 
    
         
             
            metadata: {}
         
     | 
| 
       164 
127 
     | 
    
         
             
            post_install_message:
         
     | 
| 
       165 
128 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
         @@ -169,14 +132,14 @@ required_ruby_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       169 
132 
     | 
    
         
             
              requirements:
         
     | 
| 
       170 
133 
     | 
    
         
             
              - - ">="
         
     | 
| 
       171 
134 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       172 
     | 
    
         
            -
                  version: ' 
     | 
| 
      
 135 
     | 
    
         
            +
                  version: '3.0'
         
     | 
| 
       173 
136 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       174 
137 
     | 
    
         
             
              requirements:
         
     | 
| 
       175 
138 
     | 
    
         
             
              - - ">="
         
     | 
| 
       176 
139 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       177 
140 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       178 
141 
     | 
    
         
             
            requirements: []
         
     | 
| 
       179 
     | 
    
         
            -
            rubygems_version: 3. 
     | 
| 
      
 142 
     | 
    
         
            +
            rubygems_version: 3.3.26
         
     | 
| 
       180 
143 
     | 
    
         
             
            signing_key:
         
     | 
| 
       181 
144 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       182 
145 
     | 
    
         
             
            summary: Web Push library for Ruby (RFC8030)
         
     | 
    
        data/.rspec
    DELETED
    
    
    
        data/.rubocop.yml
    DELETED
    
    | 
         @@ -1,30 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require: rubocop-performance
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            AllCops:
         
     | 
| 
       4 
     | 
    
         
            -
              Exclude:
         
     | 
| 
       5 
     | 
    
         
            -
                - 'bin/**/*'
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            Metrics/AbcSize:
         
     | 
| 
       8 
     | 
    
         
            -
              Max: 20
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
            Metrics/ClassLength:
         
     | 
| 
       11 
     | 
    
         
            -
              Max: 100
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            Metrics/ModuleLength:
         
     | 
| 
       14 
     | 
    
         
            -
              Max: 100
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            Metrics/LineLength:
         
     | 
| 
       17 
     | 
    
         
            -
              Enabled: false
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            Metrics/BlockLength:
         
     | 
| 
       20 
     | 
    
         
            -
              Exclude:
         
     | 
| 
       21 
     | 
    
         
            -
                - spec/**/*_spec.rb
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            Lint/AmbiguousBlockAssociation:
         
     | 
| 
       24 
     | 
    
         
            -
              Enabled: false
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            Style/Documentation:
         
     | 
| 
       27 
     | 
    
         
            -
              Enabled: false
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            Style/IndentHeredoc:
         
     | 
| 
       30 
     | 
    
         
            -
              Enabled: false
         
     | 
    
        data/.travis.yml
    DELETED
    
    | 
         @@ -1,24 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            env:
         
     | 
| 
       2 
     | 
    
         
            -
              global:
         
     | 
| 
       3 
     | 
    
         
            -
                - CC_TEST_REPORTER_ID=155202524386dfebe0c3267a5c868b5417ff4cc2cde8ed301fb36b177d46a458
         
     | 
| 
       4 
     | 
    
         
            -
            language: ruby
         
     | 
| 
       5 
     | 
    
         
            -
            rvm:
         
     | 
| 
       6 
     | 
    
         
            -
              - 2.2
         
     | 
| 
       7 
     | 
    
         
            -
              - 2.3
         
     | 
| 
       8 
     | 
    
         
            -
              - 2.4
         
     | 
| 
       9 
     | 
    
         
            -
              - 2.5
         
     | 
| 
       10 
     | 
    
         
            -
              - 2.6
         
     | 
| 
       11 
     | 
    
         
            -
              - 2.7
         
     | 
| 
       12 
     | 
    
         
            -
            before_install:
         
     | 
| 
       13 
     | 
    
         
            -
              - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
         
     | 
| 
       14 
     | 
    
         
            -
              - gem install bundler -v 1.17.3
         
     | 
| 
       15 
     | 
    
         
            -
            before_script:
         
     | 
| 
       16 
     | 
    
         
            -
              - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
         
     | 
| 
       17 
     | 
    
         
            -
              - chmod +x ./cc-test-reporter
         
     | 
| 
       18 
     | 
    
         
            -
              - ./cc-test-reporter before-build
         
     | 
| 
       19 
     | 
    
         
            -
            script: "bundle exec rake spec"
         
     | 
| 
       20 
     | 
    
         
            -
            after_script:
         
     | 
| 
       21 
     | 
    
         
            -
            - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
         
     | 
| 
       22 
     | 
    
         
            -
            addons:
         
     | 
| 
       23 
     | 
    
         
            -
              code_climate:
         
     | 
| 
       24 
     | 
    
         
            -
                repo_token: 155202524386dfebe0c3267a5c868b5417ff4cc2cde8ed301fb36b177d46a458
         
     | 
    
        data/CHANGELOG.md
    DELETED
    
    | 
         @@ -1,183 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # Changelog
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            ## [v1.1.0](https://github.com/zaru/webpush/tree/v1.1.0) (2020-11-16)
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v1.0.0...v1.1.0)
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            - Eliminate Ruby 2.7 warnings. [\#95](https://github.com/zaru/webpush/pull/95) ([morgoth](https://github.com/morgoth))
         
     | 
| 
       10 
     | 
    
         
            -
            - set minimum ruby version is 2.2 [\#94](https://github.com/zaru/webpush/pull/94) ([Wolfer](https://github.com/Wolfer))
         
     | 
| 
       11 
     | 
    
         
            -
            - Add proxy support [\#93](https://github.com/zaru/webpush/pull/93) ([Bugagazavr](https://github.com/Bugagazavr))
         
     | 
| 
       12 
     | 
    
         
            -
            - fix syntax error [\#91](https://github.com/zaru/webpush/pull/91) ([tonytonyjan](https://github.com/tonytonyjan))
         
     | 
| 
       13 
     | 
    
         
            -
            - change dependency gem versions [\#88](https://github.com/zaru/webpush/pull/88) ([zaru](https://github.com/zaru))
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            ## [v1.0.0](https://github.com/zaru/webpush/tree/v1.0.0) (2019-08-15)
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
            A stable version 1.0.0 has been released.
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            Thanks @mohamedhafez, @mplatov and @MedetaiAkaru for everything!
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.8...v1.0.0)
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
            - switch to aes128gcm encoding [\#84](https://github.com/zaru/webpush/pull/84) ([mohamedhafez](https://github.com/mohamedhafez))
         
     | 
| 
       26 
     | 
    
         
            -
            - Fixed fcm spec [\#77](https://github.com/zaru/webpush/pull/77) ([zaru](https://github.com/zaru))
         
     | 
| 
       27 
     | 
    
         
            -
            - add fcm endpoints [\#76](https://github.com/zaru/webpush/pull/76) ([MedetaiAkaru](https://github.com/MedetaiAkaru))
         
     | 
| 
       28 
     | 
    
         
            -
            - Add Rubocop and fix [\#74](https://github.com/zaru/webpush/pull/74) ([zaru](https://github.com/zaru))
         
     | 
| 
       29 
     | 
    
         
            -
            - Fix TravisCI bundler version [\#73](https://github.com/zaru/webpush/pull/73) ([zaru](https://github.com/zaru))
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
            ## [v0.3.8](https://github.com/zaru/webpush/tree/v0.3.8) (2019-04-16)
         
     | 
| 
       32 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.7...v0.3.8)
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
            - Fix authorization header [\#72](https://github.com/zaru/webpush/pull/72) ([xronos-i-am](https://github.com/xronos-i-am))
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
            ## [v0.3.7](https://github.com/zaru/webpush/tree/v0.3.7) (2019-03-06)
         
     | 
| 
       39 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.6...v0.3.7)
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
            - Add PEM support to import / export keys [\#65](https://github.com/zaru/webpush/pull/65) ([collimarco](https://github.com/collimarco))
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
            ## [v0.3.6](https://github.com/zaru/webpush/tree/v0.3.6) (2019-01-09)
         
     | 
| 
       46 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.5...v0.3.6)
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
            - Added a error class to arguments of raise\_error [\#62](https://github.com/zaru/webpush/pull/62) ([zaru](https://github.com/zaru))
         
     | 
| 
       51 
     | 
    
         
            -
            - Fix TravisCI bundler version [\#61](https://github.com/zaru/webpush/pull/61) ([zaru](https://github.com/zaru))
         
     | 
| 
       52 
     | 
    
         
            -
            - Raise Webpush::Unauthorized on HTTP 403 [\#59](https://github.com/zaru/webpush/pull/59) ([collimarco](https://github.com/collimarco))
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
            ## [v0.3.5](https://github.com/zaru/webpush/tree/v0.3.5) (2019-01-02)
         
     | 
| 
       55 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.4...v0.3.5)
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
            - Fix \#55 and \#51: raise the proper error based on the HTTP status code [\#58](https://github.com/zaru/webpush/pull/58) ([collimarco](https://github.com/collimarco))
         
     | 
| 
       60 
     | 
    
         
            -
            - Add urgency option [\#57](https://github.com/zaru/webpush/pull/57) ([collimarco](https://github.com/collimarco))
         
     | 
| 
       61 
     | 
    
         
            -
            - Add Rake task to generate VAPID keys [\#54](https://github.com/zaru/webpush/pull/54) ([stevenharman](https://github.com/stevenharman))
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
            ## [v0.3.4](https://github.com/zaru/webpush/tree/v0.3.4) (2018-05-25)
         
     | 
| 
       64 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.3...v0.3.4)
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
            - add http timeout options [\#50](https://github.com/zaru/webpush/pull/50) ([aishek](https://github.com/aishek))
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
            ## [v0.3.3](https://github.com/zaru/webpush/tree/v0.3.3) (2017-11-06)
         
     | 
| 
       71 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.2...v0.3.3)
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
            - Add typ to JWT header fields [\#46](https://github.com/zaru/webpush/pull/46) ([ykzts](https://github.com/ykzts))
         
     | 
| 
       76 
     | 
    
         
            -
            - Specify the version of JWT strictly [\#45](https://github.com/zaru/webpush/pull/45) ([ykzts](https://github.com/ykzts))
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
            ## [v0.3.2](https://github.com/zaru/webpush/tree/v0.3.2) (2017-07-01)
         
     | 
| 
       79 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.1...v0.3.2)
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
            - feat: improve response error codes [\#39](https://github.com/zaru/webpush/pull/39) ([glennr](https://github.com/glennr))
         
     | 
| 
       84 
     | 
    
         
            -
            - Update README.md [\#38](https://github.com/zaru/webpush/pull/38) ([kitaindia](https://github.com/kitaindia))
         
     | 
| 
       85 
     | 
    
         
            -
            - Fix code example: Add close bracket [\#37](https://github.com/zaru/webpush/pull/37) ([kuranari](https://github.com/kuranari))
         
     | 
| 
       86 
     | 
    
         
            -
            - fix code in README [\#36](https://github.com/zaru/webpush/pull/36) ([kuranari](https://github.com/kuranari))
         
     | 
| 
       87 
     | 
    
         
            -
            - Minor fix in README: Close code blocks [\#32](https://github.com/zaru/webpush/pull/32) ([nicolas-fricke](https://github.com/nicolas-fricke))
         
     | 
| 
       88 
     | 
    
         
            -
            - Copy edits for README clarifying GCM requirements [\#30](https://github.com/zaru/webpush/pull/30) ([rossta](https://github.com/rossta))
         
     | 
| 
       89 
     | 
    
         
            -
            - Adding VAPID documentation [\#28](https://github.com/zaru/webpush/pull/28) ([rossta](https://github.com/rossta))
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
            ## [v0.3.1](https://github.com/zaru/webpush/tree/v0.3.1) (2016-10-24)
         
     | 
| 
       92 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.0...v0.3.1)
         
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
            - Bug fix invalid base64 [\#29](https://github.com/zaru/webpush/pull/29) ([rossta](https://github.com/rossta))
         
     | 
| 
       97 
     | 
    
         
            -
            - Clarify VAPID usage further in README [\#27](https://github.com/zaru/webpush/pull/27) ([rossta](https://github.com/rossta))
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
            ## [v0.3.0](https://github.com/zaru/webpush/tree/v0.3.0) (2016-10-14)
         
     | 
| 
       100 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.5...v0.3.0)
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
            - Implement VAPID authorization [\#26](https://github.com/zaru/webpush/pull/26) ([rossta](https://github.com/rossta))
         
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
            ## [v0.2.5](https://github.com/zaru/webpush/tree/v0.2.5) (2016-09-14)
         
     | 
| 
       107 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.4...v0.2.5)
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
            - api key only needed for old google apis [\#24](https://github.com/zaru/webpush/pull/24) ([mohamedhafez](https://github.com/mohamedhafez))
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
            ## [v0.2.4](https://github.com/zaru/webpush/tree/v0.2.4) (2016-08-29)
         
     | 
| 
       114 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.3...v0.2.4)
         
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
            - VERIFY\_PEER by default - no need for a cert\_store option [\#20](https://github.com/zaru/webpush/pull/20) ([mohamedhafez](https://github.com/mohamedhafez))
         
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
            ## [v0.2.3](https://github.com/zaru/webpush/tree/v0.2.3) (2016-06-19)
         
     | 
| 
       121 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.2...v0.2.3)
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
            - detect and handle response errors [\#18](https://github.com/zaru/webpush/pull/18) ([mohamedhafez](https://github.com/mohamedhafez))
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
            ## [v0.2.2](https://github.com/zaru/webpush/tree/v0.2.2) (2016-06-13)
         
     | 
| 
       128 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.1...v0.2.2)
         
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
            - Don't include API key for firefox or other browsers [\#16](https://github.com/zaru/webpush/pull/16) ([mohamedhafez](https://github.com/mohamedhafez))
         
     | 
| 
       133 
     | 
    
         
            -
            - Option to specify a cert store [\#15](https://github.com/zaru/webpush/pull/15) ([mohamedhafez](https://github.com/mohamedhafez))
         
     | 
| 
       134 
     | 
    
         
            -
            - show ttl option in README [\#14](https://github.com/zaru/webpush/pull/14) ([mohamedhafez](https://github.com/mohamedhafez))
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
            ## [v0.2.1](https://github.com/zaru/webpush/tree/v0.2.1) (2016-05-23)
         
     | 
| 
       137 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.2.0...v0.2.1)
         
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
            - Make the response more detailed. [\#10](https://github.com/zaru/webpush/pull/10) ([kevinjom](https://github.com/kevinjom))
         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
            ## [v0.2.0](https://github.com/zaru/webpush/tree/v0.2.0) (2016-05-16)
         
     | 
| 
       144 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.6...v0.2.0)
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
            - Make message payload optional [\#8](https://github.com/zaru/webpush/pull/8) ([rossta](https://github.com/rossta))
         
     | 
| 
       149 
     | 
    
         
            -
            - Add specs [\#7](https://github.com/zaru/webpush/pull/7) ([rossta](https://github.com/rossta))
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
            ## [v0.1.6](https://github.com/zaru/webpush/tree/v0.1.6) (2016-05-12)
         
     | 
| 
       152 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.5...v0.1.6)
         
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
            - Add rake binstub [\#6](https://github.com/zaru/webpush/pull/6) ([rossta](https://github.com/rossta))
         
     | 
| 
       157 
     | 
    
         
            -
            - Add syntax highlighting to README snippets [\#5](https://github.com/zaru/webpush/pull/5) ([rossta](https://github.com/rossta))
         
     | 
| 
       158 
     | 
    
         
            -
            - Extract encryption module [\#4](https://github.com/zaru/webpush/pull/4) ([rossta](https://github.com/rossta))
         
     | 
| 
       159 
     | 
    
         
            -
            - Add some happy case specs [\#3](https://github.com/zaru/webpush/pull/3) ([waheedel](https://github.com/waheedel))
         
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
            ## [v0.1.5](https://github.com/zaru/webpush/tree/v0.1.5) (2016-04-29)
         
     | 
| 
       162 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.4...v0.1.5)
         
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
            **Merged pull requests:**
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
            - add Ttl header parameter [\#1](https://github.com/zaru/webpush/pull/1) ([shouta-dev](https://github.com/shouta-dev))
         
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
            ## [v0.1.4](https://github.com/zaru/webpush/tree/v0.1.4) (2016-04-27)
         
     | 
| 
       169 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.3...v0.1.4)
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
            ## [v0.1.3](https://github.com/zaru/webpush/tree/v0.1.3) (2016-04-13)
         
     | 
| 
       172 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.2...v0.1.3)
         
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
            ## [v0.1.2](https://github.com/zaru/webpush/tree/v0.1.2) (2016-04-12)
         
     | 
| 
       175 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.1...v0.1.2)
         
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
            ## [v0.1.1](https://github.com/zaru/webpush/tree/v0.1.1) (2016-03-31)
         
     | 
| 
       178 
     | 
    
         
            -
            [Full Changelog](https://github.com/zaru/webpush/compare/v0.1.0...v0.1.1)
         
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
            ## [v0.1.0](https://github.com/zaru/webpush/tree/v0.1.0) (2016-03-31)
         
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
            \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
         
     | 
    
        data/Rakefile
    DELETED
    
    
    
        data/bin/console
    DELETED
    
    | 
         @@ -1,14 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/env ruby
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require "bundler/setup"
         
     | 
| 
       4 
     | 
    
         
            -
            require "web_push"
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            # You can add fixtures and/or initialization code here to make experimenting
         
     | 
| 
       7 
     | 
    
         
            -
            # with your gem easier. You can also use a different console, if you like.
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            # (If you use this, don't forget to add pry to your Gemfile!)
         
     | 
| 
       10 
     | 
    
         
            -
            # require "pry"
         
     | 
| 
       11 
     | 
    
         
            -
            # Pry.start
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            require "irb"
         
     | 
| 
       14 
     | 
    
         
            -
            IRB.start
         
     | 
    
        data/bin/rake
    DELETED
    
    | 
         @@ -1,16 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/env ruby
         
     | 
| 
       2 
     | 
    
         
            -
            #
         
     | 
| 
       3 
     | 
    
         
            -
            # This file was generated by Bundler.
         
     | 
| 
       4 
     | 
    
         
            -
            #
         
     | 
| 
       5 
     | 
    
         
            -
            # The application 'rake' is installed as part of a gem, and
         
     | 
| 
       6 
     | 
    
         
            -
            # this file is here to facilitate running it.
         
     | 
| 
       7 
     | 
    
         
            -
            #
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            require "pathname"
         
     | 
| 
       10 
     | 
    
         
            -
            ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
         
     | 
| 
       11 
     | 
    
         
            -
              Pathname.new(__FILE__).realpath)
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            require "rubygems"
         
     | 
| 
       14 
     | 
    
         
            -
            require "bundler/setup"
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            load Gem.bin_path("rake", "rake")
         
     | 
    
        data/bin/rspec
    DELETED
    
    | 
         @@ -1,16 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/env ruby
         
     | 
| 
       2 
     | 
    
         
            -
            #
         
     | 
| 
       3 
     | 
    
         
            -
            # This file was generated by Bundler.
         
     | 
| 
       4 
     | 
    
         
            -
            #
         
     | 
| 
       5 
     | 
    
         
            -
            # The application 'rspec' is installed as part of a gem, and
         
     | 
| 
       6 
     | 
    
         
            -
            # this file is here to facilitate running it.
         
     | 
| 
       7 
     | 
    
         
            -
            #
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            require "pathname"
         
     | 
| 
       10 
     | 
    
         
            -
            ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
         
     | 
| 
       11 
     | 
    
         
            -
              Pathname.new(__FILE__).realpath)
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            require "rubygems"
         
     | 
| 
       14 
     | 
    
         
            -
            require "bundler/setup"
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            load Gem.bin_path("rspec-core", "rspec")
         
     | 
    
        data/bin/setup
    DELETED
    
    
    
        data/lib/tasks/web_push.rake
    DELETED
    
    | 
         @@ -1,14 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            namespace :web_push do
         
     | 
| 
       2 
     | 
    
         
            -
              desc 'Generate VAPID public/private key pair'
         
     | 
| 
       3 
     | 
    
         
            -
              task :generate_keys do
         
     | 
| 
       4 
     | 
    
         
            -
                require 'web_push'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
                WebPush.generate_key.tap do |keypair|
         
     | 
| 
       7 
     | 
    
         
            -
                  puts <<-KEYS
         
     | 
| 
       8 
     | 
    
         
            -
            Generated VAPID keypair:
         
     | 
| 
       9 
     | 
    
         
            -
            Public  -> #{keypair.public_key}
         
     | 
| 
       10 
     | 
    
         
            -
            Private -> #{keypair.private_key}
         
     | 
| 
       11 
     | 
    
         
            -
                  KEYS
         
     | 
| 
       12 
     | 
    
         
            -
                end
         
     | 
| 
       13 
     | 
    
         
            -
              end
         
     | 
| 
       14 
     | 
    
         
            -
            end
         
     |