Skip to content

Commit 9663a8c

Browse files
author
Matt Gaunt
committed
Extending cli and adding some tests
1 parent a9c198f commit 9663a8c

File tree

5 files changed

+213
-15
lines changed

5 files changed

+213
-15
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
coverage/
22
node_modules/
3-
wires
43
test/output/

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Web Push library for Node.js",
55
"main": "src/index.js",
66
"bin": {
7-
"web-push": "bin/web-push.js"
7+
"web-push": "src/cli.js"
88
},
99
"scripts": {
1010
"download-browser": "node --harmony ./test/helpers/download-test-browsers.js",

bin/web-push.js renamed to src/cli.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ const printUsageDetails = () => {
1414
'[--auth=<auth secret>]',
1515
'[--payload=<message>]',
1616
'[--ttl=<seconds>]',
17-
'[--vapid-subject]',
18-
'[--vapid-pubkey]',
19-
'[--vapid-pvtkey]'
17+
'[--vapid-subject=<vapid subject>]',
18+
'[--vapid-pubkey=<public key url base64>]',
19+
'[--vapid-pvtkey=<private key url base64>]',
20+
'[--gcm-api-key=<api key>]'
2021
]
2122
}, {
2223
name: 'generate-vapid-keys',
@@ -56,7 +57,9 @@ const generateVapidKeys = returnJson => {
5657
};
5758

5859
const sendNotification = args => {
59-
webPush.setGCMAPIKey(process.env.GCM_API_KEY);
60+
if (process.env.GCM_API_KEY) {
61+
webPush.setGCMAPIKey(process.env.GCM_API_KEY);
62+
}
6063

6164
const subscription = {
6265
endpoint: argv.endpoint,
@@ -68,14 +71,23 @@ const sendNotification = args => {
6871

6972
const payload = argv.payload || null;
7073

71-
const options = {
72-
TTL: argv.ttl || 0,
73-
vapid: {
74+
const options = {};
75+
76+
if (argv.ttl) {
77+
options.TTL = argv.ttl;
78+
}
79+
80+
if (argv['vapid-subject'] || argv['vapid-pubkey'] || argv['vapid-pvtkey']) {
81+
options.vapidDetails = {
7482
subject: argv['vapid-subject'] || null,
7583
publicKey: argv['vapid-pubkey'] || null,
7684
privateKey: argv['vapid-pvtkey'] || null
7785
}
78-
};
86+
}
87+
88+
if (argv['gcm-api-key']) {
89+
options.gcmAPIKey = argv['gcm-api-key'];
90+
}
7991

8092
webPush.sendNotification(subscription, payload, options)
8193
.then(() => {
@@ -93,7 +105,7 @@ const action = process.argv[2];
93105
const argv = require('minimist')(process.argv.slice(3));
94106
switch (action) {
95107
case 'send-notification':
96-
if (!argv.endpoint || !argv.key) {
108+
if (!argv.endpoint) {
97109
return printUsageDetails();
98110
}
99111

src/vapid-helper.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function generateVAPIDKeys() {
3939

4040
function validateSubject(subject) {
4141
if (!subject) {
42-
throw new Error('No subject set in vapid.subject.');
42+
throw new Error('No subject set in vapidDetails.subject.');
4343
}
4444

4545
if (typeof subject !== 'string' || subject.length === 0) {
@@ -57,7 +57,7 @@ function validateSubject(subject) {
5757

5858
function validatePublicKey(publicKey) {
5959
if (!publicKey) {
60-
throw new Error('No key set vapid.publicKey');
60+
throw new Error('No key set vapidDetails.publicKey');
6161
}
6262

6363
if (typeof publicKey !== 'string') {
@@ -74,7 +74,7 @@ function validatePublicKey(publicKey) {
7474

7575
function validatePrivateKey(privateKey) {
7676
if (!privateKey) {
77-
throw new Error('No key set in vapid.privateKey');
77+
throw new Error('No key set in vapidDetails.privateKey');
7878
}
7979

8080
if (typeof privateKey !== 'string') {
@@ -103,7 +103,7 @@ function validatePrivateKey(privateKey) {
103103
*/
104104
function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
105105
if (!audience) {
106-
throw new Error('No audience set in vapid.audience.');
106+
throw new Error('No audience could be generated for VAPID.');
107107
}
108108

109109
if (typeof audience !== 'string' || audience.length === 0) {

test/test-cli.js

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const urlBase64 = require('urlsafe-base64');
5+
const spawn = require('child_process').spawn;
6+
7+
const cliPath = 'src/cli.js';
8+
9+
suite('Test Encryption Helpers', function() {
10+
test('no args run', function() {
11+
return new Promise(resolve => {
12+
const webpushCLISpawn = spawn('node', [
13+
cliPath
14+
]);
15+
let errorData = '';
16+
let consoleOutput = '';
17+
webpushCLISpawn.stdout.on('data', data => {
18+
consoleOutput += data;
19+
});
20+
21+
webpushCLISpawn.stderr.on('data', data => {
22+
errorData += data;
23+
});
24+
25+
webpushCLISpawn.on('close', code => {
26+
// No args should have code 1
27+
assert(code, 1);
28+
29+
assert.equal(errorData, '');
30+
assert.notEqual(consoleOutput.indexOf('web-push send-notification'), -1);
31+
assert.notEqual(consoleOutput.indexOf('web-push generate-vapid-keys'), -1);
32+
resolve();
33+
});
34+
});
35+
});
36+
37+
test('test send-notification no args', function() {
38+
return new Promise(resolve => {
39+
const webpushCLISpawn = spawn('node', [
40+
cliPath,
41+
'send-notification'
42+
]);
43+
44+
webpushCLISpawn.on('close', code => {
45+
// No args should have code 1
46+
assert.equal(code, 1);
47+
resolve();
48+
});
49+
});
50+
});
51+
52+
test('test send-notification only endpoint', function() {
53+
return new Promise(resolve => {
54+
const webpushCLISpawn = spawn('node', [
55+
cliPath,
56+
'send-notification',
57+
'--endpoint=https://example.push-service.com/'
58+
]);
59+
60+
let errorData = '';
61+
let consoleOutput = '';
62+
webpushCLISpawn.stdout.on('data', data => {
63+
consoleOutput += data;
64+
});
65+
66+
webpushCLISpawn.stderr.on('data', data => {
67+
errorData += data;
68+
});
69+
70+
webpushCLISpawn.on('close', code => {
71+
assert.equal(code, 0);
72+
assert.equal(errorData, '');
73+
assert.equal(consoleOutput.indexOf('Error sending push message: '), 0);
74+
resolve();
75+
});
76+
});
77+
});
78+
79+
test('test send-notification all options', function() {
80+
return new Promise(resolve => {
81+
const webpushCLISpawn = spawn('node', [
82+
cliPath,
83+
'send-notification',
84+
'--endpoint=https://example.push-service.com/',
85+
'--key=browser-key',
86+
'--auth=auth',
87+
'--payload=hello',
88+
'--ttl=1234',
89+
'--vapid-subject=http://example.push-serice.com/contact',
90+
'--vapid-pubkey=vapid-publicKey',
91+
'--vapid-pvtkey=vapid-privateKey',
92+
'--gcm-api-key=qwerty'
93+
]);
94+
95+
let errorData = '';
96+
let consoleOutput = '';
97+
webpushCLISpawn.stdout.on('data', data => {
98+
consoleOutput += data;
99+
});
100+
101+
webpushCLISpawn.stderr.on('data', data => {
102+
errorData += data;
103+
});
104+
105+
webpushCLISpawn.on('close', code => {
106+
assert.equal(code, 0);
107+
assert.equal(errorData, '');
108+
assert.equal(consoleOutput.indexOf('Error sending push message: '), 0);
109+
resolve();
110+
});
111+
});
112+
});
113+
114+
test('test generate vapid keys', function() {
115+
return new Promise(resolve => {
116+
const webpushCLISpawn = spawn('node', [
117+
cliPath,
118+
'generate-vapid-keys'
119+
]);
120+
121+
let errorData = '';
122+
let consoleOutput = '';
123+
webpushCLISpawn.stdout.on('data', data => {
124+
consoleOutput += data;
125+
});
126+
127+
webpushCLISpawn.stderr.on('data', data => {
128+
errorData += data;
129+
});
130+
131+
webpushCLISpawn.on('close', code => {
132+
assert.equal(code, 0);
133+
assert.equal(errorData, '');
134+
assert.notEqual(consoleOutput.indexOf('Public Key:'), -1);
135+
assert.notEqual(consoleOutput.indexOf('Private Key:'), -1);
136+
137+
const lines = consoleOutput.split('\n');
138+
const publicKeyTitleIndex = lines.findIndex(line => {
139+
return line.indexOf('Public Key:') !== -1;
140+
});
141+
const publicKey = lines[publicKeyTitleIndex + 1].trim();
142+
assert.equal(urlBase64.decode(publicKey).length, 65);
143+
144+
const privateKeyTitleIndex = lines.findIndex(line => {
145+
return line.indexOf('Private Key:') !== -1;
146+
});
147+
const privateKey = lines[privateKeyTitleIndex + 1].trim();
148+
assert.equal(urlBase64.decode(privateKey).length, 32);
149+
resolve();
150+
});
151+
});
152+
});
153+
154+
test('test generate JSON vapid keys', function() {
155+
return new Promise(resolve => {
156+
const webpushCLISpawn = spawn('node', [
157+
cliPath,
158+
'generate-vapid-keys',
159+
'--json'
160+
]);
161+
162+
let errorData = '';
163+
let consoleOutput = '';
164+
webpushCLISpawn.stdout.on('data', data => {
165+
consoleOutput += data;
166+
});
167+
168+
webpushCLISpawn.stderr.on('data', data => {
169+
errorData += data;
170+
});
171+
172+
webpushCLISpawn.on('close', code => {
173+
assert.equal(code, 0);
174+
assert.equal(errorData, '');
175+
176+
const vapidKeys = JSON.parse(consoleOutput);
177+
assert(vapidKeys.publicKey);
178+
assert(vapidKeys.privateKey);
179+
180+
assert.equal(urlBase64.decode(vapidKeys.privateKey).length, 32);
181+
assert.equal(urlBase64.decode(vapidKeys.publicKey).length, 65);
182+
183+
resolve();
184+
});
185+
});
186+
});
187+
});

0 commit comments

Comments
 (0)