webpush 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/README.md +43 -15
- data/lib/webpush.rb +14 -0
- data/lib/webpush/encryption.rb +2 -2
- data/lib/webpush/request.rb +1 -1
- data/lib/webpush/vapid_key.rb +3 -3
- data/lib/webpush/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18e5c11503abaf7212ca277dd336ae64dfede00f
|
4
|
+
data.tar.gz: 10fc83dcbc3f7deb76c1a53e76e031b68aac989c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8a099a95fc658ccc3fa5c84b75e142c65e5b0f34f81c78955c1116b4b6f6c8f83d961c288cacf90b40a7fe0aa6902a235e01af2d3d4f8352b94e97e66f32feb
|
7
|
+
data.tar.gz: e468dd4c140e9e925979e20d27add5c1c74d5e6c49ecbf6ac24260147fc0ceb2a92ec636e6d6905a45fca801851620b5328992c52dca0faaf2a89e833ace9d62
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -30,7 +30,7 @@ Sending a web push message to a visitor of your website requires a number of ste
|
|
30
30
|
|
31
31
|
1. Your server has (optionally) generated (one-time) a set of [Voluntary Application server Identification (VAPID)](https://tools.ietf.org/html/draft-ietf-webpush-vapid-01) keys.
|
32
32
|
2. To send messages through Chrome, you have registered your site through the [Google Developer Console](https://console.developers.google.com/) and have obtained a GCM sender id. For using Google's deprecated GCM protocol instead of VAPID, a separate GCM API key from your app settings would also be necessary.
|
33
|
-
3. A
|
33
|
+
3. A `manifest.json` file, linked from your user's page, identifies your app settings, including the GCM sender ID.
|
34
34
|
5. Also 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, with creates a `subscription` JSON object on the client side.
|
35
35
|
6. Your server uses the `webpush` gem to send a notification with the `subscription` obtained from the client and an optional payload (the message).
|
36
36
|
7. 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.
|
@@ -75,9 +75,9 @@ Your application javascript must register a service worker script at an appropri
|
|
75
75
|
// Register the serviceWorker script at /serviceworker.js from your server if supported
|
76
76
|
if (navigator.serviceWorker) {
|
77
77
|
navigator.serviceWorker.register('/serviceworker.js')
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
.then(function(reg) {
|
79
|
+
console.log('Service worker change, registered the service worker');
|
80
|
+
});
|
81
81
|
}
|
82
82
|
// Otherwise, no push notifications :(
|
83
83
|
else {
|
@@ -87,13 +87,15 @@ else {
|
|
87
87
|
|
88
88
|
### Subscribing to push notifications
|
89
89
|
|
90
|
+
#### With VAPID
|
91
|
+
|
90
92
|
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).
|
91
93
|
|
92
94
|
```javascript
|
93
95
|
window.vapidPublicKey = new Uint8Array(<%= Base64.urlsafe_decode64(ENV['VAPID_PUBLIC_KEY']).bytes %>);
|
94
96
|
```
|
95
97
|
|
96
|
-
Your application javascript
|
98
|
+
Your application javascript uses the `navigator.serviceWorker.pushManager` to subscribe to push notifications, passing the VAPID public key to the subscription settings.
|
97
99
|
|
98
100
|
```javascript
|
99
101
|
// application.js
|
@@ -108,9 +110,21 @@ navigator.serviceWorker.ready.then((serviceWorkerRegistration) => {
|
|
108
110
|
});
|
109
111
|
```
|
110
112
|
|
111
|
-
|
112
|
-
|
113
|
-
`pushManager.subscribe` call.
|
113
|
+
#### Without VAPID
|
114
|
+
|
115
|
+
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.
|
116
|
+
|
117
|
+
```javascript
|
118
|
+
// application.js
|
119
|
+
// When serviceWorker is supported, installed, and activated,
|
120
|
+
// subscribe the pushManager property with the vapidPublicKey
|
121
|
+
navigator.serviceWorker.ready.then((serviceWorkerRegistration) => {
|
122
|
+
serviceWorkerRegistration.pushManager
|
123
|
+
.subscribe({
|
124
|
+
userVisibleOnly: true
|
125
|
+
});
|
126
|
+
});
|
127
|
+
```
|
114
128
|
|
115
129
|
### Triggering a web push notification
|
116
130
|
|
@@ -156,7 +170,7 @@ generated without the `applicationServerKey` parameter described earlier.
|
|
156
170
|
|
157
171
|
### Receiving the push event
|
158
172
|
|
159
|
-
Your `/serviceworker.js` script
|
173
|
+
Your `/serviceworker.js` script may respond to `'push'` events. One action it can take is to trigger desktop notifications by calling `showNotification` on the `registration` property.
|
160
174
|
|
161
175
|
```javascript
|
162
176
|
// serviceworker.js
|
@@ -222,11 +236,6 @@ Webpush.payload_send(
|
|
222
236
|
p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
|
223
237
|
auth: "aW1hcmthcmFpa3V6ZQ==",
|
224
238
|
ttl: 600 #optional, ttl in seconds, defaults to 2419200 (4 weeks),
|
225
|
-
vapid: {
|
226
|
-
subject: "mailto:sender@example.com",
|
227
|
-
public_key: ENV['VAPID_PUBLIC_KEY'],
|
228
|
-
private_key: ENV['VAPID_PRIVATE_KEY']
|
229
|
-
}
|
230
239
|
)
|
231
240
|
```
|
232
241
|
|
@@ -235,10 +244,29 @@ Webpush.payload_send(
|
|
235
244
|
```ruby
|
236
245
|
Webpush.payload_send(
|
237
246
|
endpoint: "https://fcm.googleapis.com/gcm/send/eah7hak....",
|
238
|
-
|
247
|
+
p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
|
248
|
+
auth: "aW1hcmthcmFpa3V6ZQ=="
|
239
249
|
)
|
240
250
|
```
|
241
251
|
|
252
|
+
### With VAPID
|
253
|
+
|
254
|
+
VAPID details are given as a hash with `:subject`, `:public_key`, and
|
255
|
+
`:private_key`. The `:subject` is a contact URI for the application server as either a "mailto:" or an "https:" address. The `:public_key` and `:private_key` should be passed as the base64-encoded values generated with `Webpush.generate_key`.
|
256
|
+
|
257
|
+
```ruby
|
258
|
+
Webpush.payload_send(
|
259
|
+
endpoint: "https://fcm.googleapis.com/gcm/send/eah7hak....",
|
260
|
+
message: "A message",
|
261
|
+
p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
|
262
|
+
auth: "aW1hcmthcmFpa3V6ZQ==",
|
263
|
+
vapid: {
|
264
|
+
subject: "mailto:sender@example.com"
|
265
|
+
public_key: ENV['VAPID_PUBLIC_KEY'],
|
266
|
+
private_key: ENV['VAPID_PRIVATE_KEY']
|
267
|
+
}
|
268
|
+
)
|
269
|
+
|
242
270
|
### ServiceWorker sample
|
243
271
|
|
244
272
|
see. https://github.com/zaru/web-push-sample
|
data/lib/webpush.rb
CHANGED
@@ -47,5 +47,19 @@ module Webpush
|
|
47
47
|
def generate_key
|
48
48
|
VapidKey.new
|
49
49
|
end
|
50
|
+
|
51
|
+
def encode64(bytes)
|
52
|
+
Base64.urlsafe_encode64(bytes)
|
53
|
+
end
|
54
|
+
|
55
|
+
def decode64(str)
|
56
|
+
# For Ruby < 2.3, Base64.urlsafe_decode64 strict decodes and will raise errors if encoded value is not properly padded
|
57
|
+
# Implementation: http://ruby-doc.org/stdlib-2.3.0/libdoc/base64/rdoc/Base64.html#method-i-urlsafe_decode64
|
58
|
+
if !str.end_with?("=") && str.length % 4 != 0
|
59
|
+
str = str.ljust((str.length + 3) & ~3, "=")
|
60
|
+
end
|
61
|
+
|
62
|
+
Base64.urlsafe_decode64(str)
|
63
|
+
end
|
50
64
|
end
|
51
65
|
end
|
data/lib/webpush/encryption.rb
CHANGED
@@ -13,12 +13,12 @@ module Webpush
|
|
13
13
|
server_public_key_bn = server.public_key.to_bn
|
14
14
|
|
15
15
|
group = OpenSSL::PKey::EC::Group.new(group_name)
|
16
|
-
client_public_key_bn = OpenSSL::BN.new(
|
16
|
+
client_public_key_bn = OpenSSL::BN.new(Webpush.decode64(p256dh), 2)
|
17
17
|
client_public_key = OpenSSL::PKey::EC::Point.new(group, client_public_key_bn)
|
18
18
|
|
19
19
|
shared_secret = server.dh_compute_key(client_public_key)
|
20
20
|
|
21
|
-
client_auth_token =
|
21
|
+
client_auth_token = Webpush.decode64(auth)
|
22
22
|
|
23
23
|
prk = HKDF.new(shared_secret, salt: client_auth_token, algorithm: 'SHA256', info: "Content-Encoding: auth\0").next_bytes(32)
|
24
24
|
|
data/lib/webpush/request.rb
CHANGED
data/lib/webpush/vapid_key.rb
CHANGED
@@ -30,7 +30,7 @@ module Webpush
|
|
30
30
|
# Convenience
|
31
31
|
# @return base64 urlsafe-encoded binary representaion of 32-byte VAPID private key
|
32
32
|
def private_key
|
33
|
-
|
33
|
+
Webpush.encode64(curve.private_key.to_s(2))
|
34
34
|
end
|
35
35
|
|
36
36
|
def public_key=(key)
|
@@ -61,11 +61,11 @@ module Webpush
|
|
61
61
|
private
|
62
62
|
|
63
63
|
def to_big_num(key)
|
64
|
-
OpenSSL::BN.new(
|
64
|
+
OpenSSL::BN.new(Webpush.decode64(key), 2)
|
65
65
|
end
|
66
66
|
|
67
67
|
def encode64(bin)
|
68
|
-
|
68
|
+
Webpush.encode64(bin)
|
69
69
|
end
|
70
70
|
|
71
71
|
def trim_encode64(bin)
|
data/lib/webpush/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webpush
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zaru@sakuraba
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hkdf
|