Skip to content

Commit

Permalink
Merge pull request #298 from auth0/fix-transaction
Browse files Browse the repository at this point in the history
Fix transaction usage to delete what is stored in local storage
  • Loading branch information
glena authored Jan 16, 2017
2 parents 49d42bb + d742ebf commit b9ffbb2
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 42 deletions.
2 changes: 1 addition & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ <h2>Console:</h2>
redirectUri: 'http://localhost:3000/example',
clientID: '3GGMIEuBPZ28lb6NBDNARaEZisqFakAs',
audience: 'https://auth0-tests-auth0js.auth0.com/userinfo',
responseType: 'token'
responseType: 'token id_token'
});

webAuth.parseHash(function(err, data) {
Expand Down
65 changes: 34 additions & 31 deletions src/web-auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ function WebAuth(options) {
responseType: { optional: true, type: 'string', message: 'responseType is not valid' },
responseMode: { optional: true, type: 'string', message: 'responseMode is not valid' },
redirectUri: { optional: true, type: 'string', message: 'redirectUri is not valid' },
scope: { optional: true, type: 'string', message: 'audience is not valid' },
audience: { optional: true, type: 'string', message: 'scope is not valid' },
scope: { optional: true, type: 'string', message: 'scope is not valid' },
audience: { optional: true, type: 'string', message: 'audience is not valid' },
leeway: { optional: true, type: 'number', message: 'leeway is not valid' },
_disableDeprecationWarnings: { optional: true, type: 'boolean', message: '_disableDeprecationWarnings option is not valid' },
_sendTelemetry: { optional: true, type: 'boolean', message: '_sendTelemetry option is not valid' },
Expand Down Expand Up @@ -83,6 +83,9 @@ WebAuth.prototype.parseHash = function (options, cb) {
var parsedQs;
var err;
var token;
var state;
var transaction;
var transactionNonce;

if (!cb && typeof options === 'function') {
cb = options;
Expand Down Expand Up @@ -114,28 +117,38 @@ WebAuth.prototype.parseHash = function (options, cb) {
return cb(null, null);
}

state = parsedQs.state || options.state;

transaction = this.transactionManager.getStoredTransaction(state);
transactionNonce = options.nonce || (transaction && transaction.nonce) || null;
transactionState = options.state || (transaction && transaction.state) || null;

if (parsedQs.id_token) {
this.validateToken(parsedQs.id_token, parsedQs.state || options.state, options.nonce, function (err, response) {
if (err) {
return cb(err);
}
this.validateToken(
parsedQs.id_token,
transactionState,
transactionNonce,
function (error, payload) {
if (error) {
return cb(error);
}

return cb(null, buildParseHashResponse(parsedQs, response));
});
return cb(null, buildParseHashResponse(parsedQs, (transaction && transaction.appStatus) || null, payload));
});
} else {
cb(null, buildParseHashResponse(parsedQs, null));
cb(null, buildParseHashResponse(parsedQs, (transaction && transaction.appStatus) || null, null));
}
};

function buildParseHashResponse(qs, token) {
function buildParseHashResponse(qs, appStatus, token) {
return {
accessToken: qs.access_token || null,
idToken: qs.id_token || null,
idTokenPayload: token && token.payload ? token.payload : null,
appStatus: token ? token.appStatus || null : null,
idTokenPayload: token || null,
appStatus: appStatus || null,
refreshToken: qs.refresh_token || null,
state: qs.state || null,
expiresIn: qs.expires_in || null,
expiresIn: qs.expires_in ? parseInt(qs.expires_in, 10) : null,
tokenType: qs.token_type || null
};
}
Expand All @@ -150,30 +163,19 @@ function buildParseHashResponse(qs, token) {
* @param {Function} cb: function(err, {payload, transaction})
*/
WebAuth.prototype.validateToken = function (token, state, nonce, cb) {
var audiences;
var transaction;
var transactionNonce;
var tokenNonce;

transaction = this.transactionManager.getStoredTransaction(state);
transactionNonce = (transaction && transaction.nonce) || nonce || null;

var verifier = new IdTokenVerifier({
issuer: this.baseOptions.token_issuer,
audience: this.baseOptions.clientID,
leeway: this.baseOptions.leeway || 0,
__disableExpirationCheck: this.baseOptions.__disableExpirationCheck
});

verifier.verify(token, transactionNonce, function (err, payload) {
verifier.verify(token, nonce, function (err, payload) {
if (err) {
return cb(error.invalidJwt(err.message));
}

cb(null, {
payload: payload,
transaction: transaction
});
cb(null, payload);
});
};

Expand Down Expand Up @@ -203,10 +205,7 @@ WebAuth.prototype.renewAuth = function (options, cb) {

params = this.transactionManager.process(params);

assert.check(params, { type: 'object', message: 'options parameter is not valid' }, {
scope: { type: 'string', message: 'scope option is required' },
audience: { type: 'string', message: 'audience option is required' }
});
assert.check(params, { type: 'object', message: 'options parameter is not valid' });
assert.check(cb, { type: 'function', message: 'cb parameter is not valid' });

params.prompt = 'none';
Expand All @@ -220,8 +219,12 @@ WebAuth.prototype.renewAuth = function (options, cb) {
return cb(err);
}

var transaction = _this.transactionManager.getStoredTransaction(params.state);
var transactionNonce = options.nonce || (transaction && transaction.nonce) || null;
var transactionState = options.state || (transaction && transaction.state) || null;

if (data.id_token) {
return _this.validateToken(data.id_token, options.state, options.nonce, function (err, payload) {
return _this.validateToken(data.id_token, transactionState, transactionNonce, function (err, payload) {
if (err) {
return cb(err);
}
Expand Down
43 changes: 33 additions & 10 deletions test/web-auth/web-auth.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
var expect = require('expect.js');
var stub = require('sinon').stub;
var spy = require('sinon').spy;
var request = require('superagent');

var storage = require('../../src/helper/storage');
var IframeHandler = require('../../src/helper/iframe-handler');

var RequestMock = require('../mock/request-mock');

var TransactionManager = require('../../src/web-auth/transaction-manager');
var SilentAuthenticationHandler = require('../../src/web-auth/silent-authentication-handler');
var WebAuth = require('../../src/web-auth');

Expand Down Expand Up @@ -84,6 +86,14 @@ describe('auth0.WebAuth', function () {
global.window.location.hash = '#access_token=asldkfjahsdlkfjhasd&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlF6RTROMFpCTTBWRFF6RTJSVVUwTnpJMVF6WTFNelE0UVRrMU16QXdNRUk0UkRneE56RTRSZyJ9.eyJpc3MiOiJodHRwczovL3dwdGVzdC5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NTVkNDhjNTdkNWIwYWQwMjIzYzQwOGQ3IiwiYXVkIjoiZ1lTTmxVNFlDNFYxWVBkcXE4elBRY3VwNnJKdzFNYnQiLCJleHAiOjE0ODI5NjkwMzEsImlhdCI6MTQ4MjkzMzAzMSwibm9uY2UiOiJhc2ZkIn0.PPoh-pITcZ8qbF5l5rMZwXiwk5efbESuqZ0IfMUcamB6jdgLwTxq-HpOT_x5q6-sO1PBHchpSo1WHeDYMlRrOFd9bh741sUuBuXdPQZ3Zb0i2sNOAC2RFB1E11mZn7uNvVPGdPTg-Y5xppz30GSXoOJLbeBszfrVDCmPhpHKGGMPL1N6HV-3EEF77L34YNAi2JQ-b70nFK_dnYmmv0cYTGUxtGTHkl64UEDLi3u7bV-kbGky3iOOCzXKzDDY6BBKpCRTc2KlbrkO2A2PuDn27WVv1QCNEFHvJN7HxiDDzXOsaUmjrQ3sfrHhzD7S9BcCRkekRfD9g95SKD5J0Fj8NA&token_type=Bearer&state=theState&refresh_token=kajshdgfkasdjhgfas';
});


beforeEach(function() {
spy(TransactionManager.prototype, "getStoredTransaction");
});
afterEach(function() {
TransactionManager.prototype.getStoredTransaction.restore();
})

it('should parse a valid hash', function (done) {
var webAuth = new WebAuth({
domain: 'wptest.auth0.com',
Expand Down Expand Up @@ -116,11 +126,13 @@ describe('auth0.WebAuth', function () {
tokenType: 'Bearer'
});

expect(TransactionManager.prototype.getStoredTransaction.calledOnce).to.be.ok();

done();
}); // eslint-disable-line
});

it('should parse a valid hash from the location.hash', function () {
it('should parse a valid hash from the location.hash', function (done) {
var webAuth = new WebAuth({
domain: 'wptest.auth0.com',
redirectUri: 'http://example.com/callback',
Expand Down Expand Up @@ -148,6 +160,10 @@ describe('auth0.WebAuth', function () {
expiresIn: null,
tokenType: 'Bearer'
});

expect(TransactionManager.prototype.getStoredTransaction.calledOnce).to.be.ok();

done();
});
});

Expand All @@ -172,6 +188,9 @@ describe('auth0.WebAuth', function () {
expiresIn: null,
tokenType: 'Bearer'
});

expect(TransactionManager.prototype.getStoredTransaction.calledOnce).to.be.ok();

done();
}); // eslint-disable-line
});
Expand Down Expand Up @@ -317,11 +336,15 @@ describe('auth0.WebAuth', function () {
beforeEach(function(){
global.window = {};
global.window.document = {};

spy(TransactionManager.prototype, "getStoredTransaction");
});

afterEach(function () {
delete global.window;
SilentAuthenticationHandler.prototype.login.restore();

TransactionManager.prototype.getStoredTransaction.restore();
});

it('should validate the token', function (done) {
Expand Down Expand Up @@ -352,17 +375,17 @@ describe('auth0.WebAuth', function () {
expect(data).to.eql({
id_token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlF6RTROMFpCTTBWRFF6RTJSVVUwTnpJMVF6WTFNelE0UVRrMU16QXdNRUk0UkRneE56RTRSZyJ9.eyJpc3MiOiJodHRwczovL3dwdGVzdC5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NTVkNDhjNTdkNWIwYWQwMjIzYzQwOGQ3IiwiYXVkIjoiZ1lTTmxVNFlDNFYxWVBkcXE4elBRY3VwNnJKdzFNYnQiLCJleHAiOjE0ODI5NjkwMzEsImlhdCI6MTQ4MjkzMzAzMSwibm9uY2UiOiJhc2ZkIn0.PPoh-pITcZ8qbF5l5rMZwXiwk5efbESuqZ0IfMUcamB6jdgLwTxq-HpOT_x5q6-sO1PBHchpSo1WHeDYMlRrOFd9bh741sUuBuXdPQZ3Zb0i2sNOAC2RFB1E11mZn7uNvVPGdPTg-Y5xppz30GSXoOJLbeBszfrVDCmPhpHKGGMPL1N6HV-3EEF77L34YNAi2JQ-b70nFK_dnYmmv0cYTGUxtGTHkl64UEDLi3u7bV-kbGky3iOOCzXKzDDY6BBKpCRTc2KlbrkO2A2PuDn27WVv1QCNEFHvJN7HxiDDzXOsaUmjrQ3sfrHhzD7S9BcCRkekRfD9g95SKD5J0Fj8NA',
idTokenPayload: {
payload: {
iss: 'https://wptest.auth0.com/',
sub: 'auth0|55d48c57d5b0ad0223c408d7',
aud: 'gYSNlU4YC4V1YPdqq8zPQcup6rJw1Mbt',
exp: 1482969031,
iat: 1482933031,
nonce: 'asfd'
},
transaction: null
iss: 'https://wptest.auth0.com/',
sub: 'auth0|55d48c57d5b0ad0223c408d7',
aud: 'gYSNlU4YC4V1YPdqq8zPQcup6rJw1Mbt',
exp: 1482969031,
iat: 1482933031,
nonce: 'asfd'
}
});

expect(TransactionManager.prototype.getStoredTransaction.calledOnce).to.be.ok();

done();
});
});
Expand Down

0 comments on commit b9ffbb2

Please sign in to comment.