Skip to content

Commit 369e6e6

Browse files
marco-cMatt Gaunt
authored andcommitted
# This is a combination of 2 commits.
# The first commit's message is: Changes to new API surface for sendNotification # This is the 2nd commit message: Add more files to .npmignore
1 parent 1d47bd0 commit 369e6e6

17 files changed

+1181
-797
lines changed

.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"max-len": [1, 80, 4, {"ignoreComments": true, "ignoreUrls": true}],
1515
"no-param-reassign": 0,
1616
"quote-props": 0,
17-
"wrap-iife": [2, "inside"]
17+
"wrap-iife": [2, "inside"],
18+
"import/no-unresolved": 0
1819
}
1920
}

.npmignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
coverage
22
test
33
test_tools
4-
4+
.travis.yml
5+
wires
6+
.eslintrc

bin/web-push.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#! /usr/bin/env node
2+
const fs = require('fs');
3+
const webPush = require('web-push');
4+
webPush.setGCMAPIKey(process.env.GCM_API_KEY);
5+
6+
const argv = require('minimist')(process.argv.slice(2));
7+
8+
const usage = 'Use: web-push --endpoint=<url> --key=<browser key> ' +
9+
'[--auth=<auth secret>] [--ttl=<seconds>] [--payload=<message>] ' +
10+
'[--vapid-audience] [--vapid-subject] [--vapid-pvtkey] [--vapid-pubkey]';
11+
12+
if (!argv.endpoint || !argv.key) {
13+
console.log(usage);
14+
process.exit(1);
15+
}
16+
17+
const endpoint = argv.endpoint;
18+
const key = argv.key;
19+
const ttl = argv.ttl || 0;
20+
const payload = argv.payload || '';
21+
const auth = argv.auth || null;
22+
const vapidAudience = argv['vapid-audience'] || null;
23+
const vapidSubject = argv['vapid-subject'] || null;
24+
const vapidPubKey = argv['vapid-pubkey'] || null;
25+
const vapidPvtKey = argv['vapid-pvtkey'] || null;
26+
27+
function getKeys() {
28+
if (vapidPubKey && vapidPvtKey) {
29+
const publicKey = fs.readFileSync(vapidPubKey);
30+
const privateKey = fs.readFileSync(vapidPvtKey);
31+
32+
if (publicKey && privateKey) {
33+
return {
34+
privateKey,
35+
publicKey
36+
};
37+
}
38+
}
39+
40+
return webPush.generateVAPIDKeys();
41+
}
42+
43+
let params = {
44+
TTL: ttl,
45+
payload,
46+
userPublicKey: key
47+
};
48+
if (vapidAudience && vapidSubject) {
49+
const vapidKeys = getKeys();
50+
const vapid = {
51+
audience: vapidAudience,
52+
subject: `mailto:${vapidSubject}`,
53+
privateKey: vapidKeys.privateKey,
54+
publicKey: vapidKeys.publicKey
55+
};
56+
params.vapid = vapid;
57+
}
58+
if (auth) {
59+
params.userAuth = auth;
60+
}
61+
webPush.sendNotification(endpoint, params).then(() => {
62+
console.log('Push message sent.');
63+
}, (err) => {
64+
console.log('Error sending push message: ', err);
65+
}).then(() => {
66+
process.exit(0);
67+
});

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
},
4343
"devDependencies": {
4444
"chalk": "^1.1.3",
45-
"chromedriver": "^2.23.1",
45+
"chromedriver": "^2.24.1",
4646
"del": "^2.2.1",
4747
"dmg": "^0.1.0",
4848
"eslint": "^2.10.2",
@@ -54,8 +54,8 @@
5454
"mocha": "^2.4.5",
5555
"portfinder": "^1.0.2",
5656
"request": "^2.69.0",
57-
"selenium-assistant": "0.4.0",
58-
"selenium-webdriver": "~2.53.2",
57+
"selenium-assistant": "0.5.3",
58+
"selenium-webdriver": "^3.0.0-beta-2",
5959
"semver": "^5.1.0",
6060
"temp": "^0.8.3"
6161
},

src/encryption-helper.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use strict';
2+
3+
const crypto = require('crypto');
4+
const ece = require('http_ece');
5+
const urlBase64 = require('urlsafe-base64');
6+
7+
// New standard, Firefox 46+ and Chrome 50+.
8+
const encrypt = function(userPublicKey, userAuth, payload) {
9+
if (!userPublicKey) {
10+
throw new Error('No user public key provided for encryption.');
11+
}
12+
13+
if (typeof userPublicKey !== 'string') {
14+
throw new Error('User auth must be a string.');
15+
}
16+
17+
if (!userAuth) {
18+
throw new Error('No user auth provided for encryption.');
19+
}
20+
21+
if (typeof userAuth !== 'string') {
22+
throw new Error('User auth must be a string.');
23+
}
24+
25+
if (userAuth.length < 22) {
26+
throw new Error('User auth should be 22 bytes or more.');
27+
}
28+
29+
if (typeof payload === 'string' || payload instanceof String) {
30+
payload = new Buffer(payload);
31+
}
32+
33+
const localCurve = crypto.createECDH('prime256v1');
34+
const localPublicKey = localCurve.generateKeys();
35+
36+
const salt = urlBase64.encode(crypto.randomBytes(16));
37+
38+
ece.saveKey('webpushKey', localCurve, 'P-256');
39+
40+
const cipherText = ece.encrypt(payload, {
41+
keyid: 'webpushKey',
42+
dh: userPublicKey,
43+
salt: salt,
44+
authSecret: userAuth,
45+
padSize: 2
46+
});
47+
48+
return {
49+
localPublicKey: localPublicKey,
50+
salt: salt,
51+
cipherText: cipherText
52+
};
53+
};
54+
55+
module.exports = {
56+
encrypt: encrypt
57+
};

0 commit comments

Comments
 (0)