Skip to content

Commit 616c2b9

Browse files
author
Matt Gaunt
committed
Sharing validation of input
1 parent da7cd2b commit 616c2b9

File tree

2 files changed

+48
-57
lines changed

2 files changed

+48
-57
lines changed

src/vapid-helper.js

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,33 +37,7 @@ function generateVAPIDKeys() {
3737
};
3838
}
3939

40-
/**
41-
* This method takes the required VAPID parameters and returns the required
42-
* header to be added to a Web Push Protocol Request.
43-
* @param {string} audience This must be the origin of the push service.
44-
* @param {string} subject This should be a URL or a 'mailto:' email
45-
* address.
46-
* @param {Buffer} publicKey The VAPID public key.
47-
* @param {Buffer} privateKey The VAPID private key.
48-
* @param {integer} [expiration] The expiration of the VAPID JWT.
49-
* @return {Object} Returns an Object with the Authorization and
50-
* 'Crypto-Key' values to be used as headers.
51-
*/
52-
function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
53-
if (!audience) {
54-
throw new Error('No audience set in vapid.audience.');
55-
}
56-
57-
if (typeof audience !== 'string' || audience.length === 0) {
58-
throw new Error('The audience value must be a string containing the ' +
59-
'origin of a push service. ' + audience);
60-
}
61-
62-
const audienceParseResult = url.parse(audience);
63-
if (!audienceParseResult.hostname) {
64-
throw new Error('VAPID audience is not a url. ' + audience);
65-
}
66-
40+
function validateSubject(subject) {
6741
if (!subject) {
6842
throw new Error('No subject set in vapid.subject.');
6943
}
@@ -79,7 +53,9 @@ function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
7953
throw new Error('Vapid subject is not a url or mailto url. ' + subject);
8054
}
8155
}
56+
}
8257

58+
function validatePublicKey(publicKey) {
8359
if (!publicKey) {
8460
throw new Error('No key set vapid.publicKey');
8561
}
@@ -94,7 +70,9 @@ function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
9470
if (publicKey.length !== 65) {
9571
throw new Error('Vapid public key should be 65 bytes long when decoded.');
9672
}
73+
}
9774

75+
function validatePrivateKey(privateKey) {
9876
if (!privateKey) {
9977
throw new Error('No key set in vapid.privateKey');
10078
}
@@ -109,6 +87,42 @@ function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
10987
if (privateKey.length !== 32) {
11088
throw new Error('Vapid private key should be 32 bytes long when decoded.');
11189
}
90+
}
91+
92+
/**
93+
* This method takes the required VAPID parameters and returns the required
94+
* header to be added to a Web Push Protocol Request.
95+
* @param {string} audience This must be the origin of the push service.
96+
* @param {string} subject This should be a URL or a 'mailto:' email
97+
* address.
98+
* @param {Buffer} publicKey The VAPID public key.
99+
* @param {Buffer} privateKey The VAPID private key.
100+
* @param {integer} [expiration] The expiration of the VAPID JWT.
101+
* @return {Object} Returns an Object with the Authorization and
102+
* 'Crypto-Key' values to be used as headers.
103+
*/
104+
function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
105+
if (!audience) {
106+
throw new Error('No audience set in vapid.audience.');
107+
}
108+
109+
if (typeof audience !== 'string' || audience.length === 0) {
110+
throw new Error('The audience value must be a string containing the ' +
111+
'origin of a push service. ' + audience);
112+
}
113+
114+
const audienceParseResult = url.parse(audience);
115+
if (!audienceParseResult.hostname) {
116+
throw new Error('VAPID audience is not a url. ' + audience);
117+
}
118+
119+
validateSubject(subject);
120+
validatePublicKey(publicKey);
121+
validatePrivateKey(privateKey);
122+
123+
publicKey = urlBase64.decode(publicKey);
124+
privateKey = urlBase64.decode(privateKey);
125+
112126

113127
if (expiration) {
114128
// TODO: Check if expiration is valid and use it in place of the hard coded
@@ -140,5 +154,8 @@ function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
140154

141155
module.exports = {
142156
generateVAPIDKeys: generateVAPIDKeys,
143-
getVapidHeaders: getVapidHeaders
157+
getVapidHeaders: getVapidHeaders,
158+
validateSubject: validateSubject,
159+
validatePublicKey: validatePublicKey,
160+
validatePrivateKey: validatePrivateKey
144161
};

src/web-push-lib.js

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -55,35 +55,9 @@ WebPushLib.prototype.setVapidDetails =
5555
return;
5656
}
5757

58-
if (typeof subject !== 'string' || subject.length === 0) {
59-
throw new Error('The subject should be a URL or mailto:');
60-
}
61-
62-
if (subject.indexOf('mailto:') !== 0) {
63-
// Must be a url if it doesn't have mailto at the start
64-
const subjectParseResult = url.parse(subject);
65-
if (!subjectParseResult.hostname) {
66-
throw new Error('Vapid subject is not a url or mailto url. ' + subject);
67-
}
68-
}
69-
70-
if (typeof publicKey !== 'string') {
71-
throw new Error('The vapid public key must be a url safe Base 64 ' +
72-
'encoded string.');
73-
}
74-
75-
if (urlBase64.decode(publicKey).length !== 65) {
76-
throw new Error('The vapid public key must be 65 bytes once decoded.');
77-
}
78-
79-
if (typeof privateKey !== 'string') {
80-
throw new Error('The vapid private key must be a url safe Base 64 ' +
81-
'encoded string.');
82-
}
83-
84-
if (urlBase64.decode(privateKey).length !== 32) {
85-
throw new Error('The vapid private key must be 65 bytes once decoded.');
86-
}
58+
vapidHelper.validateSubject(subject);
59+
vapidHelper.validatePublicKey(publicKey);
60+
vapidHelper.validatePrivateKey(privateKey);
8761

8862
vapidDetails = {
8963
subject: subject,

0 commit comments

Comments
 (0)