diff --git a/CHANGELOG.md b/CHANGELOG.md index ace5f26..cabb45b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,3 +20,9 @@ * Manual transaction state checking: call `transaction.getState` to get the state without relying on an open websocket or automatic polling. * Know the result of otp code validation (SMS / TOTP) without relying on a socket. * Allow to confirm the enrollment after serializing the transaction. + +# [v1.0.1](https://github.com/auth0/auth0-guardian.js/tree/v1.0.1) (2017-03-01) +[Full Changelog](https://github.com/auth0/auth0-guardian.js/compare/v1.0.1...v1.0.0) + +**Fix** +- Callback with invalid token error when resuming transaction instead of throwing it [\#29](https://github.com/auth0/auth0-guardian.js/pull/29) ([dafortune](https://github.com/dafortune)). diff --git a/lib/errors/index.js b/lib/errors/index.js index e01d21e..0be18a2 100644 --- a/lib/errors/index.js +++ b/lib/errors/index.js @@ -14,3 +14,4 @@ exports.EnrollmentMethodDisabledError = require('./enrollment_method_disabled_er exports.InvalidEnrollmentError = require('./invalid_enrollment_error'); exports.InvalidStateError = require('./invalid_state_error'); exports.UnexpectedInputError = require('./unexpected_input_error'); +exports.InvalidToken = require('./invalid_token'); diff --git a/lib/errors/invalid_token.js b/lib/errors/invalid_token.js new file mode 100644 index 0000000..6dd35b8 --- /dev/null +++ b/lib/errors/invalid_token.js @@ -0,0 +1,16 @@ +'use strict'; + +var object = require('../utils/object'); +var GuardianError = require('./guardian_error'); + +function InvalidToken(message) { + GuardianError.call(this, { + message: message, + errorCode: 'invalid_token' + }); +} + +InvalidToken.prototype = object.create(GuardianError.prototype); +InvalidToken.prototype.constructor = InvalidToken; + +module.exports = InvalidToken; diff --git a/lib/index.js b/lib/index.js index 6ac8634..719efa3 100644 --- a/lib/index.js +++ b/lib/index.js @@ -157,48 +157,59 @@ auth0GuardianJS.prototype.start = function start(callback) { */ auth0GuardianJS.resume = function resume(options, transactionState, callback) { - var transactionTokenObject = jwtToken(transactionState.transactionToken); - var txId = transactionTokenObject.getDecoded().txid; + try { + var transactionTokenObject; + transactionTokenObject = jwtToken(transactionState.transactionToken); - // create httpClient/socketClient - var httpClientInstance = object.get(options, 'dependencies.httpClient', - httpClient(transactionState.baseUrl, txId)); + var txId = transactionTokenObject.getDecoded().txid; - var transport = options.transport || options.stateCheckingMechanism || 'socket'; + // create httpClient/socketClient + var httpClientInstance = object.get(options, 'dependencies.httpClient', + httpClient(transactionState.baseUrl, txId)); - if (transactionTokenObject.isExpired()) { - asyncHelpers.setImmediate(callback, new errors.CredentialsExpiredError()); - return; - } - - var socketClient = clientFactory.create({ - serviceUrl: transactionState.baseUrl, - transport: transport, - httpClient: httpClientInstance, - dependency: object.get(options, 'dependencies.socketClient') - }); - - // connect - socketClient.connect(transactionState.transactionToken, - function onSocketConnection(connectErr) { - if (connectErr) { - callback(connectErr); - return; - } - var tx; + var transport = options.transport || options.stateCheckingMechanism || 'socket'; - try { - tx = transactionFactory.fromTransactionState(transactionState, { - transactionEventsReceiver: socketClient, - httpClient: httpClientInstance - }); - } catch (transactionBuildingErr) { - callback(transactionBuildingErr); - return; - } + if (transactionTokenObject.isExpired()) { + asyncHelpers.setImmediate(callback, new errors.CredentialsExpiredError()); + return; + } - callback(null, tx); + var socketClient = clientFactory.create({ + serviceUrl: transactionState.baseUrl, + transport: transport, + httpClient: httpClientInstance, + dependency: object.get(options, 'dependencies.socketClient') }); + + // connect + socketClient.connect(transactionState.transactionToken, + function onSocketConnection(connectErr) { + if (connectErr) { + callback(connectErr); + return; + } + var tx; + + try { + tx = transactionFactory.fromTransactionState(transactionState, { + transactionEventsReceiver: socketClient, + httpClient: httpClientInstance + }); + } catch (transactionBuildingErr) { + callback(transactionBuildingErr); + return; + } + + callback(null, tx); + }); + } catch (err) { + if (err.name === 'InvalidTokenError') { + asyncHelpers.setImmediate(callback, new errors.InvalidToken('Invalid transaction token')); + return; + } + + asyncHelpers.setImmediate(callback, err); + } }; diff --git a/package.json b/package.json index 287e1c7..36a199c 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "auth0-guardian-js", - "version": "1.0.0", + "version": "1.0.1", "description": "Interface", "main": "index.js", "directories": { "test": "test" }, "dependencies": { - "jwt-decode": "^2.1.0", + "jwt-decode": "^2.2.0", "socket.io-client": "^1.5.0", "superagent": "^2.3.0" }, diff --git a/test/index.test.js b/test/index.test.js index 965c1ab..a33939b 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -539,6 +539,18 @@ describe('guardian.js', function () { }; }); + describe('when token is invalid', function () { + it('callbacks with a enrolled transaction', function (done) { + guardianjsb.resume(options, '123', (err) => { + expect(err).to.exist; + expect(err.message).to.equal('Invalid transaction token'); + expect(err.errorCode).to.equal('invalid_token'); + + done(); + }); + }); + }); + it('callbacks with a enrolled transaction', function (done) { guardianjsb.resume(options, serializedTransaction, (err, tx) => { expect(err).not.to.exist;