Skip to content

Commit

Permalink
Sharing validation of input
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Gaunt committed Sep 21, 2016
1 parent da7cd2b commit 616c2b9
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 57 deletions.
73 changes: 45 additions & 28 deletions src/vapid-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,7 @@ function generateVAPIDKeys() {
};
}

/**
* This method takes the required VAPID parameters and returns the required
* header to be added to a Web Push Protocol Request.
* @param {string} audience This must be the origin of the push service.
* @param {string} subject This should be a URL or a 'mailto:' email
* address.
* @param {Buffer} publicKey The VAPID public key.
* @param {Buffer} privateKey The VAPID private key.
* @param {integer} [expiration] The expiration of the VAPID JWT.
* @return {Object} Returns an Object with the Authorization and
* 'Crypto-Key' values to be used as headers.
*/
function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
if (!audience) {
throw new Error('No audience set in vapid.audience.');
}

if (typeof audience !== 'string' || audience.length === 0) {
throw new Error('The audience value must be a string containing the ' +
'origin of a push service. ' + audience);
}

const audienceParseResult = url.parse(audience);
if (!audienceParseResult.hostname) {
throw new Error('VAPID audience is not a url. ' + audience);
}

function validateSubject(subject) {
if (!subject) {
throw new Error('No subject set in vapid.subject.');
}
Expand All @@ -79,7 +53,9 @@ function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
throw new Error('Vapid subject is not a url or mailto url. ' + subject);
}
}
}

function validatePublicKey(publicKey) {
if (!publicKey) {
throw new Error('No key set vapid.publicKey');
}
Expand All @@ -94,7 +70,9 @@ function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
if (publicKey.length !== 65) {
throw new Error('Vapid public key should be 65 bytes long when decoded.');
}
}

function validatePrivateKey(privateKey) {
if (!privateKey) {
throw new Error('No key set in vapid.privateKey');
}
Expand All @@ -109,6 +87,42 @@ function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
if (privateKey.length !== 32) {
throw new Error('Vapid private key should be 32 bytes long when decoded.');
}
}

/**
* This method takes the required VAPID parameters and returns the required
* header to be added to a Web Push Protocol Request.
* @param {string} audience This must be the origin of the push service.
* @param {string} subject This should be a URL or a 'mailto:' email
* address.
* @param {Buffer} publicKey The VAPID public key.
* @param {Buffer} privateKey The VAPID private key.
* @param {integer} [expiration] The expiration of the VAPID JWT.
* @return {Object} Returns an Object with the Authorization and
* 'Crypto-Key' values to be used as headers.
*/
function getVapidHeaders(audience, subject, publicKey, privateKey, expiration) {
if (!audience) {
throw new Error('No audience set in vapid.audience.');
}

if (typeof audience !== 'string' || audience.length === 0) {
throw new Error('The audience value must be a string containing the ' +
'origin of a push service. ' + audience);
}

const audienceParseResult = url.parse(audience);
if (!audienceParseResult.hostname) {
throw new Error('VAPID audience is not a url. ' + audience);
}

validateSubject(subject);
validatePublicKey(publicKey);
validatePrivateKey(privateKey);

publicKey = urlBase64.decode(publicKey);
privateKey = urlBase64.decode(privateKey);


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

module.exports = {
generateVAPIDKeys: generateVAPIDKeys,
getVapidHeaders: getVapidHeaders
getVapidHeaders: getVapidHeaders,
validateSubject: validateSubject,
validatePublicKey: validatePublicKey,
validatePrivateKey: validatePrivateKey
};
32 changes: 3 additions & 29 deletions src/web-push-lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,35 +55,9 @@ WebPushLib.prototype.setVapidDetails =
return;
}

if (typeof subject !== 'string' || subject.length === 0) {
throw new Error('The subject should be a URL or mailto:');
}

if (subject.indexOf('mailto:') !== 0) {
// Must be a url if it doesn't have mailto at the start
const subjectParseResult = url.parse(subject);
if (!subjectParseResult.hostname) {
throw new Error('Vapid subject is not a url or mailto url. ' + subject);
}
}

if (typeof publicKey !== 'string') {
throw new Error('The vapid public key must be a url safe Base 64 ' +
'encoded string.');
}

if (urlBase64.decode(publicKey).length !== 65) {
throw new Error('The vapid public key must be 65 bytes once decoded.');
}

if (typeof privateKey !== 'string') {
throw new Error('The vapid private key must be a url safe Base 64 ' +
'encoded string.');
}

if (urlBase64.decode(privateKey).length !== 32) {
throw new Error('The vapid private key must be 65 bytes once decoded.');
}
vapidHelper.validateSubject(subject);
vapidHelper.validatePublicKey(publicKey);
vapidHelper.validatePrivateKey(privateKey);

vapidDetails = {
subject: subject,
Expand Down

0 comments on commit 616c2b9

Please sign in to comment.