Skip to content

Commit

Permalink
change jwt.sign to return errors on callback instead of throwing errors
Browse files Browse the repository at this point in the history
  • Loading branch information
jfromaniello committed May 19, 2016
1 parent 65aadb4 commit 1e46c5a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 10 deletions.
25 changes: 16 additions & 9 deletions sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,20 @@ module.exports = function(payload, secretOrPrivateKey, options, callback) {
typ: typeof payload === 'object' ? 'JWT' : undefined
}, options.header);

function failure (err) {
if (callback) {
return callback(err);
}
throw err;
}

if (typeof payload === 'undefined') {
throw new Error('payload is required');
return failure(new Error('payload is required'));
} else if (typeof payload === 'object') {
var payload_validation_result = registered_claims_schema.validate(payload);

if (payload_validation_result.error) {
throw payload_validation_result.error;
return failure(payload_validation_result.error);
}

payload = xtend(payload);
Expand All @@ -64,22 +71,22 @@ module.exports = function(payload, secretOrPrivateKey, options, callback) {
});

if (invalid_options.length > 0) {
throw new Error('invalid ' + invalid_options.join(',') + ' option for ' + (typeof payload ) + ' payload' );
return failure(new Error('invalid ' + invalid_options.join(',') + ' option for ' + (typeof payload ) + ' payload' ));
}
}

if (typeof payload.exp !== 'undefined' && typeof options.expiresIn !== 'undefined') {
throw new Error('Bad "options.expiresIn" option the payload already has an "exp" property.');
return failure(new Error('Bad "options.expiresIn" option the payload already has an "exp" property.'));
}

if (typeof payload.nbf !== 'undefined' && typeof options.notBefore !== 'undefined') {
throw new Error('Bad "options.notBefore" option the payload already has an "nbf" property.');
return failure(new Error('Bad "options.notBefore" option the payload already has an "nbf" property.'));
}

var validation_result = sign_options_schema.validate(options);

if (validation_result.error) {
throw validation_result.error;
return failure(validation_result.error);
}

var timestamp = payload.iat || Math.floor(Date.now() / 1000);
Expand All @@ -93,22 +100,22 @@ module.exports = function(payload, secretOrPrivateKey, options, callback) {
if (typeof options.notBefore !== 'undefined') {
payload.nbf = timespan(options.notBefore);
if (typeof payload.nbf === 'undefined') {
throw new Error('"notBefore" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60');
return failure(new Error('"notBefore" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));
}
}

if (typeof options.expiresIn !== 'undefined' && typeof payload === 'object') {
payload.exp = timespan(options.expiresIn);
if (typeof payload.exp === 'undefined') {
throw new Error('"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60');
return failure(new Error('"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));
}
}

Object.keys(options_to_payload).forEach(function (key) {
var claim = options_to_payload[key];
if (typeof options[key] !== 'undefined') {
if (typeof payload[claim] !== 'undefined') {
throw new Error('Bad "options.' + key + '" option. The payload already has an "' + claim + '" property.');
return failure(new Error('Bad "options.' + key + '" option. The payload already has an "' + claim + '" property.'));
}
payload[claim] = options[key];
}
Expand Down
18 changes: 17 additions & 1 deletion test/async_sign.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,28 @@ describe('signing a token asynchronously', function() {
});
});

it('should throw error', function(done) {
it('should return error when secret is not a cert for RS256', function(done) {
//this throw an error because the secret is not a cert and RS256 requires a cert.
jwt.sign({ foo: 'bar' }, secret, { algorithm: 'RS256' }, function (err) {
expect(err).to.be.ok();
done();
});
});

it('should return error on wrong arguments', function(done) {
//this throw an error because the secret is not a cert and RS256 requires a cert.
jwt.sign({ foo: 'bar' }, secret, { notBefore: {} }, function (err) {
expect(err).to.be.ok();
done();
});
});

it('should return error on wrong arguments (2)', function(done) {
jwt.sign('string', 'secret', {noTimestamp: true}, function (err) {
expect(err).to.be.ok();
expect(err).to.be.instanceof(Error);
done();
});
});
});
});

0 comments on commit 1e46c5a

Please sign in to comment.