Skip to content
This repository has been archived by the owner on Apr 23, 2021. It is now read-only.

Commit

Permalink
Merge pull request #2 from GoogleChrome/initial-docs
Browse files Browse the repository at this point in the history
Some basic docs to get started with
  • Loading branch information
wibblymat committed Mar 31, 2016
2 parents 087b86b + eea6b3d commit bd407f5
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 51 deletions.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,43 @@ This library provides the functions necessary to encrypt a payload for sending
with the Web Push protocol. It also includes a helper function for actually
send the message to the Web Push endpoint.

What is this for?
-----------------

The [Push API](http://w3c.github.io/push-api/) allow users to subscribe for
notifications from a web site, which can be delivered to them even if the
browser has been closed. This was first shipped as part of Chrome 42, but the
push message could not contain any payload data.

As of Chrome 50 and Firefox 44 (desktop-only) payloads are supported, but the
server must encrypt the payload or the receiving browser will reject it.

This library implements the necessary encryption as a Node module.

Overview
--------

Install the module using npm:

`npm install web-push-encryption`

Require the module:

`var webpush = require('web-push-encryption');`

Send a message:

`webpush.sendWebPush('Yay! Web Push!', subscription);`

If the push service requires an authentication header (notably Google Cloud
Messaging, used by Chrome) then you can add that as a third parameter:

```
if (subscription.endpoint.indexOf('https://android.googleapis.com/gcm/send/') === 0) {
webpush.sendWebPush('A message for Chrome', subscription, MY_GCM_KEY);
}
```

Support
-------

Expand Down
3 changes: 1 addition & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,5 @@ const push = require('./push');
// Exports the public API
module.exports = {
encrypt: encrypt,
sendWebPush: push.sendWebPush,
addAuthToken: push.addAuthToken
sendWebPush: push.sendWebPush
};
58 changes: 9 additions & 49 deletions src/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,68 +33,31 @@ function ub64(buffer) {
.replace(/\=/g, '');
}

/**
* A helper for creating the value part of the HTTP encryption headers
* @param {String} name The name of the header field
* @param {Buffer} value The value of the field
* @return {String} String representation of the header
*/
function createHeaderField(name, value) {
return `${name}=${ub64(value)}`;
}

const authTokens = [];

/**
* Returns the appropriate authentication token, if any, for the endpoint we are
* trying to send to.
* @param {String} endpoint URL of the endpoint
* @return {String} The authentication token
*/
function getAuthToken(endpoint) {
for (let i = 0; i < authTokens.length; i++) {
if (endpoint.indexOf(authTokens[i].pattern) !== -1) {
return authTokens[i].token;
}
}
}

/**
* Adds a new authentication token. The pattern is a simple string. An endpoint
* will use the given authentication token if the pattern is a substring of the
* endpoint.
* @param {String} pattern The pattern to match on
* @param {String} token The authentication token
*/
function addAuthToken(pattern, token) {
authTokens.push({pattern, token});
}

/**
* Sends a message using the Web Push protocol
* @param {String} message The message to send
* @param {Object} subscription The subscription details for the client we
* are sending to
* @param {String} authToken Optional token to be used in the
* `Authentication` header if the endpoint
* requires it.
* @return {Promise} A promise that resolves if the push was sent successfully
* with status and body.
*/
function sendWebPush(message, subscription) {
let endpoint = subscription.endpoint;
const authToken = getAuthToken(endpoint);

function sendWebPush(message, subscription, authToken) {
// If the endpoint is GCM then we temporarily need to rewrite it, as not all
// GCM servers support the Web Push protocol. This should go away in the
// future.
endpoint = endpoint.replace(GCM_URL, TEMP_GCM_URL);
const endpoint = subscription.endpoint.replace(GCM_URL, TEMP_GCM_URL);

const payload = encrypt(message, subscription);
const headers = {
'Encryption': createHeaderField('salt', payload.salt),
'Crypto-Key': createHeaderField('dh', payload.serverPublicKey)
'Encryption': `salt=${ub64(payload.salt)}`,
'Crypto-Key': `dh=${ub64(payload.serverPublicKey)}`
};

if (authToken) {
headers.Authorization = 'key=' + authToken;
headers.Authorization = `key=${authToken}`;
}

return new Promise(function(resolve, reject) {
Expand All @@ -114,7 +77,4 @@ function sendWebPush(message, subscription) {
});
}

module.exports = {
sendWebPush,
addAuthToken
};
module.exports = {sendWebPush};

0 comments on commit bd407f5

Please sign in to comment.