Skip to content

Commit 6f02d24

Browse files
author
Matt Gaunt
committed
merging
1 parent 4efbc22 commit 6f02d24

File tree

2 files changed

+82
-46
lines changed

2 files changed

+82
-46
lines changed

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ const webPush = new WebPushLib();
88

99
module.exports = {
1010
encrypt: encryptionHelper.encrypt,
11+
getVapidHeaders: vapidHelper.getVapidHeaders,
1112
generateVAPIDKeys: vapidHelper.generateVAPIDKeys,
1213
setGCMAPIKey: webPush.setGCMAPIKey,
1314
setVapidDetails: webPush.setVapidDetails,
15+
generateRequestDetails: webPush.generateRequestDetails,
1416
sendNotification: webPush.sendNotification
1517
};

src/web-push-lib.js

Lines changed: 80 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -66,38 +66,38 @@ WebPushLib.prototype.setVapidDetails =
6666
};
6767
};
6868

69-
/**
70-
* To send a push notification call this method with a subscription, optional
71-
* payload and any options.
72-
* @param {PushSubscription} subscription The PushSubscription you wish to
73-
* send the notification to.
74-
* @param {string} [payload] The payload you wish to send to the
75-
* the user.
76-
* @param {Object} [options] Options for the GCM API key and
77-
* vapid keys can be passed in if they are unique for each notification you
78-
* wish to send.
79-
* @return {Promise} This method returns a Promise which
80-
* resolves if the sending of the notification was successful, otherwise it
81-
* rejects.
82-
*/
83-
WebPushLib.prototype.sendNotification =
69+
/**
70+
* To send a push notification call this method with a subscription, optional
71+
* payload and any options.
72+
* @param {PushSubscription} subscription The PushSubscription you wish to
73+
* send the notification to.
74+
* @param {string} [payload] The payload you wish to send to the
75+
* the user.
76+
* @param {Object} [options] Options for the GCM API key and
77+
* vapid keys can be passed in if they are unique for each notification you
78+
* wish to send.
79+
* @return {Promise} This method returns a Promise which
80+
* resolves if the sending of the notification was successful, otherwise it
81+
* rejects.
82+
*/
83+
WebPushLib.prototype.generateRequestDetails =
8484
function(subscription, payload, options) {
8585
if (!subscription || !subscription.endpoint) {
86-
return Promise.reject('You must pass in a subscription with at least ' +
86+
throw new Error('You must pass in a subscription with at least ' +
8787
'an endpoint.');
8888
}
8989

9090
if (typeof subscription.endpoint !== 'string' ||
9191
subscription.endpoint.length === 0) {
92-
return Promise.reject('The subscription endpoint must be a string with ' +
92+
throw new Error('The subscription endpoint must be a string with ' +
9393
'a valid URL.');
9494
}
9595

9696
if (payload) {
9797
// Validate the subscription keys
9898
if (!subscription.keys || !subscription.keys.p256dh ||
9999
!subscription.keys.auth) {
100-
return Promise.reject('To send a message with a payload, the ' +
100+
throw new Error('To send a message with a payload, the ' +
101101
'subscription must have \'auth\' and \'p256dh\' keys.');
102102
}
103103
}
@@ -116,7 +116,7 @@ WebPushLib.prototype.sendNotification =
116116
for (let i = 0; i < optionKeys.length; i += 1) {
117117
const optionKey = optionKeys[i];
118118
if (validOptionKeys.indexOf(optionKey) === -1) {
119-
return Promise.reject('\'' + optionKey + '\' is an invalid option. ' +
119+
throw new Error('\'' + optionKey + '\' is an invalid option. ' +
120120
'The valid options are [\'' + validOptionKeys.join('\', \'') +
121121
'\'].');
122122
}
@@ -139,7 +139,7 @@ WebPushLib.prototype.sendNotification =
139139
timeToLive = DEFAULT_TTL;
140140
}
141141

142-
const requestOptions = {
142+
const requestDetails = {
143143
method: 'POST',
144144
headers: {
145145
TTL: timeToLive
@@ -152,27 +152,24 @@ WebPushLib.prototype.sendNotification =
152152
typeof subscription !== 'object' ||
153153
!subscription.keys.p256dh ||
154154
!subscription.keys.auth) {
155-
return Promise.reject(new Error('Unable to send a message with ' +
155+
throw new Error(new Error('Unable to send a message with ' +
156156
'payload to this subscription since it doesn\'t have the ' +
157157
'required encryption keys'));
158158
}
159159

160-
try {
161-
const encrypted = encryptionHelper.encrypt(
162-
subscription.keys.p256dh, subscription.keys.auth, payload);
160+
try {
161+
const encrypted = encryptionHelper.encrypt(
162+
subscription.keys.p256dh, subscription.keys.auth, payload);
163163

164-
requestOptions.headers['Content-Length'] = encrypted.cipherText.length;
165-
requestOptions.headers['Content-Type'] = 'application/octet-stream';
166-
requestOptions.headers['Content-Encoding'] = 'aesgcm';
167-
requestOptions.headers.Encryption = 'salt=' + encrypted.salt;
168-
requestOptions.headers['Crypto-Key'] = 'dh=' + urlBase64.encode(encrypted.localPublicKey);
164+
requestOptions.headers['Content-Length'] = encrypted.cipherText.length;
165+
requestOptions.headers['Content-Type'] = 'application/octet-stream';
166+
requestOptions.headers['Content-Encoding'] = 'aesgcm';
167+
requestOptions.headers.Encryption = 'salt=' + encrypted.salt;
168+
requestOptions.headers['Crypto-Key'] = 'dh=' + urlBase64.encode(encrypted.localPublicKey);
169169

170-
requestPayload = encrypted.cipherText;
171-
} catch (err) {
172-
return Promise.reject(err);
173-
}
170+
requestPayload = encrypted.cipherText;
174171
} else {
175-
requestOptions.headers['Content-Length'] = 0;
172+
requestDetails.headers['Content-Length'] = 0;
176173
}
177174

178175
const isGCM = subscription.endpoint.indexOf(
@@ -183,7 +180,7 @@ WebPushLib.prototype.sendNotification =
183180
console.warn('Attempt to send push notification to GCM endpoint, ' +
184181
'but no GCM key is defined'.bold.red);
185182
} else {
186-
requestOptions.headers.Authorization = 'key=' + currentGCMAPIKey;
183+
requestDetails.headers.Authorization = 'key=' + currentGCMAPIKey;
187184
}
188185
} else if (currentVapidDetails) {
189186
const parsedUrl = url.parse(subscription.endpoint);
@@ -197,22 +194,59 @@ WebPushLib.prototype.sendNotification =
197194
currentVapidDetails.privateKey
198195
);
199196

200-
requestOptions.headers.Authorization = vapidHeaders.Authorization;
201-
if (requestOptions.headers['Crypto-Key']) {
202-
requestOptions.headers['Crypto-Key'] += ';' +
197+
requestDetails.headers.Authorization = vapidHeaders.Authorization;
198+
if (requestDetails.headers['Crypto-Key']) {
199+
requestDetails.headers['Crypto-Key'] += ';' +
203200
vapidHeaders['Crypto-Key'];
204201
} else {
205-
requestOptions.headers['Crypto-Key'] = vapidHeaders['Crypto-Key'];
202+
requestDetails.headers['Crypto-Key'] = vapidHeaders['Crypto-Key'];
206203
}
207204
}
208205

206+
requestDetails.payload = requestPayload;
207+
requestDetails.endpoint = subscription.endpoint;
208+
209+
return requestDetails;
210+
};
211+
212+
/**
213+
* To send a push notification call this method with a subscription, optional
214+
* payload and any options.
215+
* @param {PushSubscription} subscription The PushSubscription you wish to
216+
* send the notification to.
217+
* @param {string} [payload] The payload you wish to send to the
218+
* the user.
219+
* @param {Object} [options] Options for the GCM API key and
220+
* vapid keys can be passed in if they are unique for each notification you
221+
* wish to send.
222+
* @return {Promise} This method returns a Promise which
223+
* resolves if the sending of the notification was successful, otherwise it
224+
* rejects.
225+
*/
226+
WebPushLib.prototype.sendNotification =
227+
function(subscription, payload, options) {
228+
let requestDetails;
229+
try {
230+
requestDetails = this.generateRequestDetails(
231+
subscription, payload, options);
232+
} catch (err) {
233+
return Promise.reject(err);
234+
}
235+
209236
return new Promise(function(resolve, reject) {
210-
const urlParts = url.parse(subscription.endpoint);
211-
requestOptions.hostname = urlParts.hostname;
212-
requestOptions.port = urlParts.port;
213-
requestOptions.path = urlParts.path;
237+
console.log(requestDetails);
238+
239+
const httpsOptions = {};
240+
const urlParts = url.parse(requestDetails.endpoint);
241+
httpsOptions.hostname = urlParts.hostname;
242+
httpsOptions.port = urlParts.port;
243+
httpsOptions.path = urlParts.path;
244+
245+
httpsOptions.headers = requestDetails.headers;
246+
247+
console.log(httpsOptions);
214248

215-
const pushRequest = https.request(requestOptions, function(pushResponse) {
249+
const pushRequest = https.request(httpsOptions, function(pushResponse) {
216250
let responseText = '';
217251

218252
pushResponse.on('data', function(chunk) {
@@ -237,8 +271,8 @@ WebPushLib.prototype.sendNotification =
237271
reject(e);
238272
});
239273

240-
if (requestPayload) {
241-
pushRequest.write(requestPayload);
274+
if (requestDetails.payload) {
275+
pushRequest.write(requestDetails.payload);
242276
}
243277

244278
pushRequest.end();

0 commit comments

Comments
 (0)