diff --git a/lib/token.js b/lib/token.js index f5d6639c6..43d9e7d97 100644 --- a/lib/token.js +++ b/lib/token.js @@ -343,6 +343,10 @@ function getIdToken(sdk, oauthOptions, options) { throw new AuthSdkError('A clientId must be specified in the OktaAuth constructor to get an idToken'); } + if (util.isString(oauthParams.responseType) && oauthParams.responseType.indexOf(' ') !== -1) { + throw new AuthSdkError('Multiple OAuth responseTypes must be defined as an array'); + } + // Convert our params to their actual OAuth equivalents var oauthQueryHash = util.removeNils({ 'client_id': oauthParams.clientId, @@ -357,6 +361,10 @@ function getIdToken(sdk, oauthOptions, options) { 'idp': oauthParams.idp }); + if (Array.isArray(oauthQueryHash['response_type'])) { + oauthQueryHash['response_type'] = oauthQueryHash['response_type'].join(' '); + } + if (oauthParams.scope.indexOf('openid') !== -1) { oauthQueryHash.scope = oauthParams.scope.join(' '); } else { @@ -379,26 +387,69 @@ function getIdToken(sdk, oauthOptions, options) { function handleOAuthResponse(res) { if (res['error'] || res['error_description']) { throw new OAuthError(res['error'], res['error_description']); + } - } else if (res['id_token']) { - if (res.state !== oauthParams.state) { - throw new AuthSdkError('OAuth flow response state doesn\'t match request state'); - } + if (res.state !== oauthParams.state) { + throw new AuthSdkError('OAuth flow response state doesn\'t match request state'); + } + + // If we're passed an array of tokenTypes, + // we return an array in the order specified. + // Otherwise, we return only the token requested + var tokenTypes = oauthParams.responseType; + var scopes = oauthQueryHash.scope.split(' '); + var tokenDict = {}; + if (res['id_token']) { var jwt = sdk.idToken.decode(res['id_token']); if (jwt.payload.nonce !== oauthParams.nonce) { throw new AuthSdkError('OAuth flow response nonce doesn\'t match request nonce'); } validateClaims(jwt.payload, sdk.options.url, oauthParams.clientId); - return { + + var idToken = { idToken: res['id_token'], - claims: jwt.payload + claims: jwt.payload, + expiresAt: jwt.payload.exp, + scopes: scopes }; - } else { + if (Array.isArray(tokenTypes)) { + tokenDict['id_token'] = idToken; + } else { + return idToken; + } + } + + if (res['access_token']) { + var accessToken = { + accessToken: res['access_token'], + expiresAt: Number(res['expires_in']) + Math.floor(Date.now()/1000), + tokenType: res['token_type'], + scopes: scopes + }; + + if (Array.isArray(tokenTypes)) { + tokenDict['token'] = accessToken; + } else { + return accessToken; + } + } + + if (!tokenDict['token'] && !tokenDict['id_token']) { throw new AuthSdkError('Unable to parse OAuth flow response'); } + + var tokens = []; + + // Create token array in the order of the responseType array + for (var t = 0, tl = tokenTypes.length; t < tl; t++) { + var tokenType = tokenTypes[t]; + tokens.push(tokenDict[tokenType]); + } + + return tokens; } function getOrigin(url) { diff --git a/test/spec/oauth.js b/test/spec/oauth.js index 79951cca6..7c803c892 100644 --- a/test/spec/oauth.js +++ b/test/spec/oauth.js @@ -1,148 +1,8 @@ /* eslint-disable complexity, max-statements */ define(function(require) { - var util = require('../util/util'); var oauthUtil = require('../util/oauthUtil'); var tokens = require('../util/tokens'); - /* - { - 'sub': '00u1pcla5qYIREDLWCQV', - 'name': 'Len Boyette', - 'given_name': 'Len', - 'family_name': 'Boyette', - 'updated_at': 1446153401, - 'email': 'lboyette@okta.com', - 'email_verified': true, - 'ver': 1, - 'iss': 'https://lboyette.trexcloud.com', - 'login': 'admin@okta.com', - 'nonce': standardNonce, - 'aud': 'NPSfOkH5eZrTy8PMDlvx', - 'iat': 2449696330, - 'exp': 1449699930, - 'amr': [ - 'kba', - 'mfa', - 'pwd' - ], - 'jti': 'TRZT7RCiSymTs5W7Ryh3', - 'auth_time': 1449696330 - } - */ - var expiredBeforeIssuedToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzd' + - 'WIiOiIwMHUxcGNsYTVxWUlSRURMV0NRViIsIm5hbWUiOiJMZW4g' + - 'Qm95ZXR0ZSIsImdpdmVuX25hbWUiOiJMZW4iLCJmYW1pbHlfbmF' + - 'tZSI6IkJveWV0dGUiLCJ1cGRhdGVkX2F0IjoxNDQ2MTUzNDAxLC' + - 'JlbWFpbCI6Imxib3lldHRlQG9rdGEuY29tIiwiZW1haWxfdmVya' + - 'WZpZWQiOnRydWUsInZlciI6MSwiaXNzIjoiaHR0cHM6Ly9sYm95' + - 'ZXR0ZS50cmV4Y2xvdWQuY29tIiwibG9naW4iOiJhZG1pbkBva3R' + - 'hLmNvbSIsIm5vbmNlIjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW' + - 'FhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhY' + - 'WFhYSIsImF1ZCI6Ik5QU2ZPa0g1ZVpyVHk4UE1EbHZ4IiwiaWF0' + - 'IjoyNDQ5Njk2MzMwLCJleHAiOjE0NDk2OTk5MzAsImFtciI6WyJ' + - 'rYmEiLCJtZmEiLCJwd2QiXSwianRpIjoiVFJaVDdSQ2lTeW1Ucz' + - 'VXN1J5aDMiLCJhdXRoX3RpbWUiOjE0NDk2OTYzMzB9.u7ClfS2w' + - '7O_kei5gtBfY_M01WCxLZ30A8KUhkHd2bDzkHFKmc3c4OT86PKS' + - '3I-JKeRIflXTwcIe8IUqtFGv8pM9iAT_mi2nxieMqOdrFw4S8UM' + - 'KKgPcYLLfFCvcDs_1d0XqHHohmHKdM6YIsgP8abPk2ugwSX49Dz' + - 'LyJrVkCZIM'; - - function setupPopup(opts) { - var src; - var fakeWindow = { - location: { - hash: '' - }, - closed: false, - close: function() { - this.closed = true; - } - }; - spyOn(fakeWindow, 'close').and.callThrough(); - - spyOn(window, 'open').and.callFake(function(s) { - src = s; - setTimeout(function() { - if (opts.closePopup) { - fakeWindow.close(); - } else { - fakeWindow.location.hash = opts.changeToHash; - } - }); - return fakeWindow; - }); - - function popupWasCreated() { - expect(window.open).toHaveBeenCalled(); - } - - function popupWasDestroyed() { - expect(fakeWindow.close).toHaveBeenCalled(); - } - - return oauthUtil.setup(opts) - .then(function() { - popupWasCreated(); - popupWasDestroyed(); - if (opts.postMessageSrc) { - var actual = util.parseUri(src); - var expected = opts.postMessageSrc; - expect(actual.baseUri).toEqual(expected.baseUri); - expect(actual.queryParams).toEqual(expected.queryParams); - } - }); - } - - function expectErrorToEqual(actual, expected) { - expect(actual.name).toEqual(expected.name); - expect(actual.message).toEqual(expected.message); - expect(actual.errorCode).toEqual(expected.errorCode); - expect(actual.errorSummary).toEqual(expected.errorSummary); - if (expected.errorLink) { - expect(actual.errorLink).toEqual(expected.errorLink); - expect(actual.errorId).toEqual(expected.errorId); - expect(actual.errorCauses).toEqual(expected.errorCauses); - } else { - expect(actual.errorLink).toBeUndefined(); - expect(actual.errorId).toBeUndefined(); - expect(actual.errorCauses).toBeUndefined(); - } - } - - function itErrorsCorrectly(title, options, error) { - it(title, function () { - var thrown = false; - try { - oauthUtil.setupFrame(options); - } catch (e) { - expectErrorToEqual(e, error); - thrown = true; - } - expect(thrown).toEqual(true); - }); - } - - function itpErrorsCorrectly(title, options, error) { - it(title, function (done) { - options.willFail = true; - var setupMethod; - if (options.authorizeArgs && - (options.authorizeArgs.responseMode === 'fragment' || options.authorizeArgs.idp)) { - setupMethod = setupPopup; - } else { - setupMethod = oauthUtil.setupFrame; - } - setupMethod(options) - .then(function() { - expect('not to be hit').toEqual(true); - }) - .fail(function(e) { - expectErrorToEqual(e, error); - }) - .fin(done); - }); - } - describe('OAuth Methods', function () { describe('idToken.refresh', function () { @@ -204,7 +64,7 @@ define(function(require) { }); it('returns id_token using idp', function (done) { - return setupPopup({ + return oauthUtil.setupPopup({ authorizeArgs: { clientId: 'NPSfOkH5eZrTy8PMDlvx', redirectUri: 'https://lboyette.trexcloud.com/redirect', @@ -244,7 +104,7 @@ define(function(require) { }); it('returns id_token using popup fragment', function (done) { - return setupPopup({ + return oauthUtil.setupPopup({ hrefMock: 'https://lboyette.trexcloud.com', changeToHash: '#id_token=' + tokens.standardIdToken + '&state=' + oauthUtil.mockedState, authorizeArgs: { @@ -335,6 +195,12 @@ define(function(require) { 'prompt': 'none', 'sessionToken': 'testToken' } + }, + expectedResp: { + idToken: tokens.standardIdToken, + claims: tokens.standardIdTokenClaims, + expiresAt: 1449699930, + scopes: ['openid', 'testscope'] } }) .fin(done); @@ -366,7 +232,7 @@ define(function(require) { }); describe('errors', function() { - itErrorsCorrectly('throws an error when openid scope isn\'t specified', + oauthUtil.itErrorsCorrectly('throws an error when openid scope isn\'t specified', { authorizeArgs: { clientId: 'NPSfOkH5eZrTy8PMDlvx', @@ -385,7 +251,7 @@ define(function(require) { errorCauses: [] } ); - itErrorsCorrectly('throws an error when clientId isn\'t specified', + oauthUtil.itErrorsCorrectly('throws an error when clientId isn\'t specified', { authorizeArgs: { redirectUri: 'https://lboyette.trexcloud.com/redirect', @@ -402,7 +268,7 @@ define(function(require) { errorCauses: [] } ); - itpErrorsCorrectly('throws an oauth error on issue', + oauthUtil.itpErrorsCorrectly('throws an oauth error on issue', { authorizeArgs: { clientId: 'NPSfOkH5eZrTy8PMDlvx', @@ -421,7 +287,7 @@ define(function(require) { errorSummary: 'something went wrong' } ); - itpErrorsCorrectly('throws an oauth error on issue with a fragment response', + oauthUtil.itpErrorsCorrectly('throws an oauth error on issue with a fragment response', { authorizeArgs: { clientId: 'NPSfOkH5eZrTy8PMDlvx', @@ -440,7 +306,7 @@ define(function(require) { errorSummary: 'The requested scope is invalid, unknown, or malformed.' } ); - itpErrorsCorrectly('throws an error when window is closed manually with a fragment', + oauthUtil.itpErrorsCorrectly('throws an error when window is closed manually with a fragment', { authorizeArgs: { clientId: 'NPSfOkH5eZrTy8PMDlvx', @@ -461,7 +327,7 @@ define(function(require) { errorCauses: [] } ); - itpErrorsCorrectly('throws an error when window is closed manually with a postMessage', + oauthUtil.itpErrorsCorrectly('throws an error when window is closed manually with a postMessage', { authorizeArgs: { clientId: 'NPSfOkH5eZrTy8PMDlvx', @@ -480,7 +346,7 @@ define(function(require) { errorCauses: [] } ); - itpErrorsCorrectly('throws an sdk error when state doesn\'t match', + oauthUtil.itpErrorsCorrectly('throws an sdk error when state doesn\'t match', { authorizeArgs: { clientId: 'NPSfOkH5eZrTy8PMDlvx', @@ -502,7 +368,7 @@ define(function(require) { errorCauses: [] } ); - itpErrorsCorrectly('throws an sdk error when nonce doesn\'t match', + oauthUtil.itpErrorsCorrectly('throws an sdk error when nonce doesn\'t match', { authorizeArgs: { clientId: 'NPSfOkH5eZrTy8PMDlvx', @@ -521,7 +387,7 @@ define(function(require) { errorCauses: [] } ); - itpErrorsCorrectly('throws an sdk error when issuer doesn\'t match', + oauthUtil.itpErrorsCorrectly('throws an sdk error when issuer doesn\'t match', { oktaAuthArgs: { url: 'https://different.issuer.com', @@ -542,7 +408,7 @@ define(function(require) { errorCauses: [] } ); - itpErrorsCorrectly('throws an sdk error when audience doesn\'t match', + oauthUtil.itpErrorsCorrectly('throws an sdk error when audience doesn\'t match', { authorizeArgs: { clientId: 'differentAudience', @@ -560,7 +426,7 @@ define(function(require) { errorCauses: [] } ); - itpErrorsCorrectly('throws an sdk error when token expired before it was issued', + oauthUtil.itpErrorsCorrectly('throws an sdk error when token expired before it was issued', { authorizeArgs: { clientId: 'NPSfOkH5eZrTy8PMDlvx', @@ -568,7 +434,7 @@ define(function(require) { sessionToken: 'testToken' }, postMessageResp: { - 'id_token': expiredBeforeIssuedToken, + 'id_token': tokens.expiredBeforeIssuedToken, state: oauthUtil.mockedState } }, @@ -582,7 +448,7 @@ define(function(require) { errorCauses: [] } ); - itpErrorsCorrectly('throws an sdk error when token is expired', + oauthUtil.itpErrorsCorrectly('throws an sdk error when token is expired', { time: 9999999999, authorizeArgs: { @@ -601,7 +467,7 @@ define(function(require) { errorCauses: [] } ); - itpErrorsCorrectly('throws an sdk error when token is issued in the future', + oauthUtil.itpErrorsCorrectly('throws an sdk error when token is issued in the future', { time: 0, authorizeArgs: { diff --git a/test/spec/token.js b/test/spec/token.js index 9a2fcf1e7..4bb50e282 100644 --- a/test/spec/token.js +++ b/test/spec/token.js @@ -58,5 +58,209 @@ define(function(require) { done(); }); }); + + it('returns access_token using sessionToken', function (done) { + return oauthUtil.setupFrame({ + oktaAuthArgs: { + url: 'https://lboyette.trexcloud.com', + clientId: 'NPSfOkH5eZrTy8PMDlvx', + redirectUri: 'https://lboyette.trexcloud.com/redirect' + }, + getWithoutPromptArgs: { + responseType: 'token', + sessionToken: 'testSessionToken' + }, + postMessageSrc: { + baseUri: 'https://lboyette.trexcloud.com/oauth2/v1/authorize', + queryParams: { + 'client_id': 'NPSfOkH5eZrTy8PMDlvx', + 'redirect_uri': 'https://lboyette.trexcloud.com/redirect', + 'response_type': 'token', + 'response_mode': 'okta_post_message', + 'state': oauthUtil.mockedState, + 'nonce': oauthUtil.mockedNonce, + 'scope': 'openid email', + 'prompt': 'none', + 'sessionToken': 'testSessionToken' + } + }, + time: 1449699929, + postMessageResp: { + 'access_token': tokens.standardAccessToken, + 'token_type': 'Bearer', + 'expires_in': 3600, + 'state': oauthUtil.mockedState + }, + expectedResp: { + accessToken: tokens.standardAccessToken, + expiresAt: 1449703529, + scopes: ['openid', 'email'], + tokenType: 'Bearer' + } + }) + .fin(function() { + done(); + }); + }); + + it('returns id_token and access_token (in that order) using an array of responseTypes', function (done) { + return oauthUtil.setupFrame({ + oktaAuthArgs: { + url: 'https://lboyette.trexcloud.com', + clientId: 'NPSfOkH5eZrTy8PMDlvx', + redirectUri: 'https://lboyette.trexcloud.com/redirect' + }, + getWithoutPromptArgs: { + responseType: ['id_token', 'token'], + sessionToken: 'testSessionToken' + }, + postMessageSrc: { + baseUri: 'https://lboyette.trexcloud.com/oauth2/v1/authorize', + queryParams: { + 'client_id': 'NPSfOkH5eZrTy8PMDlvx', + 'redirect_uri': 'https://lboyette.trexcloud.com/redirect', + 'response_type': 'id_token token', + 'response_mode': 'okta_post_message', + 'state': oauthUtil.mockedState, + 'nonce': oauthUtil.mockedNonce, + 'scope': 'openid email', + 'prompt': 'none', + 'sessionToken': 'testSessionToken' + } + }, + time: 1449699929, + postMessageResp: { + 'id_token': tokens.standardIdToken, + 'access_token': tokens.standardAccessToken, + 'token_type': 'Bearer', + 'expires_in': 3600, + 'state': oauthUtil.mockedState + }, + expectedResp: [{ + idToken: tokens.standardIdToken, + claims: tokens.standardIdTokenClaims, + expiresAt: 1449699930, + scopes: ['openid', 'email'] + }, { + accessToken: tokens.standardAccessToken, + expiresAt: 1449703529, + scopes: ['openid', 'email'], + tokenType: 'Bearer' + }] + }) + .fin(function() { + done(); + }); + }); + + it('returns access_token and id_token (in that order) using an array of responseTypes', function (done) { + return oauthUtil.setupFrame({ + oktaAuthArgs: { + url: 'https://lboyette.trexcloud.com', + clientId: 'NPSfOkH5eZrTy8PMDlvx', + redirectUri: 'https://lboyette.trexcloud.com/redirect' + }, + getWithoutPromptArgs: { + responseType: ['token', 'id_token'], + sessionToken: 'testSessionToken' + }, + postMessageSrc: { + baseUri: 'https://lboyette.trexcloud.com/oauth2/v1/authorize', + queryParams: { + 'client_id': 'NPSfOkH5eZrTy8PMDlvx', + 'redirect_uri': 'https://lboyette.trexcloud.com/redirect', + 'response_type': 'token id_token', + 'response_mode': 'okta_post_message', + 'state': oauthUtil.mockedState, + 'nonce': oauthUtil.mockedNonce, + 'scope': 'openid email', + 'prompt': 'none', + 'sessionToken': 'testSessionToken' + } + }, + time: 1449699929, + postMessageResp: { + 'id_token': tokens.standardIdToken, + 'access_token': tokens.standardAccessToken, + 'token_type': 'Bearer', + 'expires_in': 3600, + 'state': oauthUtil.mockedState + }, + expectedResp: [{ + accessToken: tokens.standardAccessToken, + expiresAt: 1449703529, + scopes: ['openid', 'email'], + tokenType: 'Bearer' + }, { + idToken: tokens.standardIdToken, + claims: tokens.standardIdTokenClaims, + expiresAt: 1449699930, + scopes: ['openid', 'email'] + }] + }) + .fin(function() { + done(); + }); + }); + + it('returns a single token using an array with a single responseType', function (done) { + return oauthUtil.setupFrame({ + oktaAuthArgs: { + url: 'https://lboyette.trexcloud.com', + clientId: 'NPSfOkH5eZrTy8PMDlvx', + redirectUri: 'https://lboyette.trexcloud.com/redirect' + }, + getWithoutPromptArgs: { + responseType: ['id_token'], + sessionToken: 'testSessionToken' + }, + postMessageSrc: { + baseUri: 'https://lboyette.trexcloud.com/oauth2/v1/authorize', + queryParams: { + 'client_id': 'NPSfOkH5eZrTy8PMDlvx', + 'redirect_uri': 'https://lboyette.trexcloud.com/redirect', + 'response_type': 'id_token', + 'response_mode': 'okta_post_message', + 'state': oauthUtil.mockedState, + 'nonce': oauthUtil.mockedNonce, + 'scope': 'openid email', + 'prompt': 'none', + 'sessionToken': 'testSessionToken' + } + }, + expectedResp: [{ + idToken: tokens.standardIdToken, + claims: tokens.standardIdTokenClaims, + expiresAt: 1449699930, + scopes: ['openid', 'email'] + }] + }) + .fin(function() { + done(); + }); + }); + + oauthUtil.itErrorsCorrectly('throws an error if multiple responseTypes are sent as a string', + { + oktaAuthArgs: { + url: 'https://lboyette.trexcloud.com', + clientId: 'NPSfOkH5eZrTy8PMDlvx', + redirectUri: 'https://lboyette.trexcloud.com/redirect' + }, + getWithoutPromptArgs: { + responseType: 'id_token token', + sessionToken: 'testSessionToken' + } + }, + { + name: 'AuthSdkError', + message: 'Multiple OAuth responseTypes must be defined as an array', + errorCode: 'INTERNAL', + errorSummary: 'Multiple OAuth responseTypes must be defined as an array', + errorLink: 'INTERNAL', + errorId: 'INTERNAL', + errorCauses: [] + } + ); }); }); diff --git a/test/util/oauthUtil.js b/test/util/oauthUtil.js index a0a9e5b06..efcd2224f 100644 --- a/test/util/oauthUtil.js +++ b/test/util/oauthUtil.js @@ -25,7 +25,9 @@ define(function(require) { var defaultResponse = { idToken: tokens.standardIdToken, - claims: tokens.standardIdTokenClaims + claims: tokens.standardIdTokenClaims, + expiresAt: 1449699930, + scopes: ['openid', 'email'] }; oauthUtil.setup = function(opts) { @@ -83,9 +85,25 @@ define(function(require) { } return promise .then(function(res) { - var expectedResp = defaultResponse; - expect(res.idToken).toEqual(expectedResp.idToken); - expect(res.claims).toEqual(expectedResp.claims); + var expectedResp = opts.expectedResp || defaultResponse; + + function expectResponsesToEqual(actual, expected) { + expect(actual.idToken).toEqual(expected.idToken); + expect(actual.claims).toEqual(expected.claims); + expect(actual.accessToken).toEqual(expected.accessToken); + expect(actual.expiresAt).toEqual(expected.expiresAt); + expect(actual.tokenType).toEqual(expected.tokenType); + } + + if (Array.isArray(expectedResp)) { + expect(res.length).toEqual(expectedResp.length); + var rl = res.length; + while(rl--) { + expectResponsesToEqual(res[rl], expectedResp[rl]); + } + } else { + expectResponsesToEqual(res, expectedResp); + } }) .fail(function(err) { if (opts.willFail) { @@ -141,5 +159,102 @@ define(function(require) { }); }; + oauthUtil.setupPopup = function(opts) { + var src; + var fakeWindow = { + location: { + hash: '' + }, + closed: false, + close: function() { + this.closed = true; + } + }; + spyOn(fakeWindow, 'close').and.callThrough(); + + spyOn(window, 'open').and.callFake(function(s) { + src = s; + setTimeout(function() { + if (opts.closePopup) { + fakeWindow.close(); + } else { + fakeWindow.location.hash = opts.changeToHash; + } + }); + return fakeWindow; + }); + + function popupWasCreated() { + expect(window.open).toHaveBeenCalled(); + } + + function popupWasDestroyed() { + expect(fakeWindow.close).toHaveBeenCalled(); + } + + return oauthUtil.setup(opts) + .then(function() { + popupWasCreated(); + popupWasDestroyed(); + if (opts.postMessageSrc) { + var actual = util.parseUri(src); + var expected = opts.postMessageSrc; + expect(actual.baseUri).toEqual(expected.baseUri); + expect(actual.queryParams).toEqual(expected.queryParams); + } + }); + }; + + function expectErrorToEqual(actual, expected) { + expect(actual.name).toEqual(expected.name); + expect(actual.message).toEqual(expected.message); + expect(actual.errorCode).toEqual(expected.errorCode); + expect(actual.errorSummary).toEqual(expected.errorSummary); + if (expected.errorLink) { + expect(actual.errorLink).toEqual(expected.errorLink); + expect(actual.errorId).toEqual(expected.errorId); + expect(actual.errorCauses).toEqual(expected.errorCauses); + } else { + expect(actual.errorLink).toBeUndefined(); + expect(actual.errorId).toBeUndefined(); + expect(actual.errorCauses).toBeUndefined(); + } + } + + oauthUtil.itErrorsCorrectly = function(title, options, error) { + it(title, function () { + var thrown = false; + try { + oauthUtil.setupFrame(options); + } catch (e) { + expectErrorToEqual(e, error); + thrown = true; + } + expect(thrown).toEqual(true); + }); + }; + + oauthUtil.itpErrorsCorrectly = function(title, options, error) { + it(title, function (done) { + options.willFail = true; + var setupMethod; + if (options.authorizeArgs && + (options.authorizeArgs.responseMode === 'fragment' || options.authorizeArgs.idp)) { + setupMethod = oauthUtil.setupPopup; + } else { + setupMethod = oauthUtil.setupFrame; + } + setupMethod(options) + .then(function() { + expect('not to be hit').toEqual(true); + }) + .fail(function(e) { + expectErrorToEqual(e, error); + }) + .fin(done); + }); + }; + + return oauthUtil; }); diff --git a/test/util/tokens.js b/test/util/tokens.js index 75de68653..0abcc357e 100644 --- a/test/util/tokens.js +++ b/test/util/tokens.js @@ -65,5 +65,63 @@ define(function() { 'auth_time': 1449696330 }; + tokens.standardAccessToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXIiOj' + + 'EsImp0aSI6IkFULnJ2Ym5TNGlXdTJhRE5jYTNid1RmMEg5Z' + + 'VdjV2xsS1FlaU5ZX1ZlSW1NWkEiLCJpc3MiOiJodHRwczov' + + 'L2xib3lldHRlLnRyZXhjbG91ZC5jb20vYXMvb3JzMXJnM3p' + + '5YzhtdlZUSk8wZzciLCJhdWQiOiJodHRwczovL2xib3lldH' + + 'RlLnRyZXhjbG91ZC5jb20vYXMvb3JzMXJnM3p5YzhtdlZUS' + + 'k8wZzciLCJzdWIiOiIwMHUxcGNsYTVxWUlSRURMV0NRViIs' + + 'ImlhdCI6MTQ2ODQ2NzY0NywiZXhwIjoxNDY4NDcxMjQ3LCJ' + + 'jaWQiOiJQZjBhaWZyaFladTF2MFAxYkZGeiIsInVpZCI6Ij' + + 'AwdTFwY2xhNXFZSVJFRExXQ1FWIiwic2NwIjpbIm9wZW5pZ' + + 'CIsImVtYWlsIl19.ziKfS8IjSdOdTHCZllTDnLFdE96U9bS' + + 'IsJzI0MQ0zlnM2QiiA7nvS54k6Xy78ebnkJvmeMCctjXVKk' + + 'JOEhR6vs11qVmIgbwZ4--MqUIRU3WoFEsr0muLl039QrUa1' + + 'EQ9-Ua9rPOMaO0pFC6h2lfB_HfzGifXATKsN-wLdxk6cgA'; + + /* + { + 'sub': '00u1pcla5qYIREDLWCQV', + 'name': 'Len Boyette', + 'given_name': 'Len', + 'family_name': 'Boyette', + 'updated_at': 1446153401, + 'email': 'lboyette@okta.com', + 'email_verified': true, + 'ver': 1, + 'iss': 'https://lboyette.trexcloud.com', + 'login': 'admin@okta.com', + 'nonce': standardNonce, + 'aud': 'NPSfOkH5eZrTy8PMDlvx', + 'iat': 2449696330, + 'exp': 1449699930, + 'amr': [ + 'kba', + 'mfa', + 'pwd' + ], + 'jti': 'TRZT7RCiSymTs5W7Ryh3', + 'auth_time': 1449696330 + } + */ + tokens.expiredBeforeIssuedToken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzd' + + 'WIiOiIwMHUxcGNsYTVxWUlSRURMV0NRViIsIm5hbWUiOiJMZW4g' + + 'Qm95ZXR0ZSIsImdpdmVuX25hbWUiOiJMZW4iLCJmYW1pbHlfbmF' + + 'tZSI6IkJveWV0dGUiLCJ1cGRhdGVkX2F0IjoxNDQ2MTUzNDAxLC' + + 'JlbWFpbCI6Imxib3lldHRlQG9rdGEuY29tIiwiZW1haWxfdmVya' + + 'WZpZWQiOnRydWUsInZlciI6MSwiaXNzIjoiaHR0cHM6Ly9sYm95' + + 'ZXR0ZS50cmV4Y2xvdWQuY29tIiwibG9naW4iOiJhZG1pbkBva3R' + + 'hLmNvbSIsIm5vbmNlIjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW' + + 'FhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhY' + + 'WFhYSIsImF1ZCI6Ik5QU2ZPa0g1ZVpyVHk4UE1EbHZ4IiwiaWF0' + + 'IjoyNDQ5Njk2MzMwLCJleHAiOjE0NDk2OTk5MzAsImFtciI6WyJ' + + 'rYmEiLCJtZmEiLCJwd2QiXSwianRpIjoiVFJaVDdSQ2lTeW1Ucz' + + 'VXN1J5aDMiLCJhdXRoX3RpbWUiOjE0NDk2OTYzMzB9.u7ClfS2w' + + '7O_kei5gtBfY_M01WCxLZ30A8KUhkHd2bDzkHFKmc3c4OT86PKS' + + '3I-JKeRIflXTwcIe8IUqtFGv8pM9iAT_mi2nxieMqOdrFw4S8UM' + + 'KKgPcYLLfFCvcDs_1d0XqHHohmHKdM6YIsgP8abPk2ugwSX49Dz' + + 'LyJrVkCZIM'; + return tokens; });