New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@okta/okta-auth-js

Package Overview
Dependencies
Maintainers
1
Versions
159
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@okta/okta-auth-js - npm Package Compare versions

Comparing version 2.5.0 to 2.6.0

karma.conf.js

14

fetch/fetchRequest.js

@@ -15,8 +15,18 @@ /*!

/* eslint-disable complexity */
function fetchRequest(method, url, args) {
var body = args.data;
var headers = args.headers || {};
var contentType = (headers['Content-Type'] || headers['content-type'] || '');
// JSON encode body (if appropriate)
if (contentType === 'application/json' && body && typeof body !== 'string') {
body = JSON.stringify(body);
}
var fetchPromise = fetch(url, {
method: method,
headers: args.headers,
body: JSON.stringify(args.data),
credentials: 'include'
body: body,
credentials: args.withCredentials === false ? 'omit' : 'include'
})

@@ -23,0 +33,0 @@ .then(function(response) {

4

jest.server.js

@@ -19,3 +19,5 @@ var packageJson = require('./package.json');

'./test/spec/tokenManager.js',
'./test/spec/webfinger.js'
'./test/spec/webfinger.js',
'./test/spec/pkce.js',
'./test/spec/features.js'
],

@@ -22,0 +24,0 @@ 'reporters': [

@@ -16,2 +16,3 @@ /*!

function jqueryRequest(method, url, args) {
// TODO: support content-type
var deferred = $.Deferred();

@@ -24,3 +25,3 @@ $.ajax({

xhrFields: {
withCredentials: true
withCredentials: args.withCredentials
}

@@ -27,0 +28,0 @@ })

@@ -40,2 +40,4 @@ /*!

userinfoUrl: util.removeTrailingSlash(args.userinfoUrl),
tokenUrl: util.removeTrailingSlash(args.tokenUrl),
grantType: args.grantType,
redirectUri: args.redirectUri,

@@ -48,2 +50,6 @@ httpRequestClient: args.httpRequestClient,

if (this.options.grantType === 'authorization_code' && !sdk.features.isPKCESupported()) {
throw new AuthSdkError('This browser doesn\'t support PKCE');
}
this.userAgent = 'okta-auth-js-' + config.SDK_VERSION;

@@ -156,2 +162,6 @@

proto.features.isPKCESupported = function() {
return proto.features.isTokenVerifySupported();
};
// { username, password, (relayState), (context) }

@@ -158,0 +168,0 @@ proto.signIn = function (opts) {

@@ -41,2 +41,12 @@ /*!

storageUtil.getPKCEStorage = function() {
if (storageUtil.browserHasLocalStorage()) {
return storageBuilder(storageUtil.getLocalStorage(), config.PKCE_STORAGE_NAME);
} else if (storageUtil.browserHasSessionStorage()) {
return storageBuilder(storageUtil.getSessionStorage(), config.PKCE_STORAGE_NAME);
} else {
return storageBuilder(storageUtil.getCookieStorage(), config.PKCE_STORAGE_NAME);
}
};
storageUtil.getHttpCache = function() {

@@ -43,0 +53,0 @@ if (storageUtil.browserHasLocalStorage()) {

@@ -83,2 +83,5 @@ /*!

// Hoist feature detection functions to static type
OktaAuth.features = OktaAuthBuilder.prototype.features;
return OktaAuth;

@@ -85,0 +88,0 @@ };

@@ -12,3 +12,4 @@ module.exports = {

"CACHE_STORAGE_NAME": "okta-cache-storage",
"SDK_VERSION": "2.5.0"
"PKCE_STORAGE_NAME": "okta-pkce-storage",
"SDK_VERSION": "2.6.0"
};

@@ -27,2 +27,3 @@ /*!

accessToken = options.accessToken,
withCredentials = options.withCredentials !== false, // default value is true
storageUtil = sdk.options.storageUtil,

@@ -53,3 +54,4 @@ storage = storageUtil.storage,

headers: headers,
data: args || undefined
data: args || undefined,
withCredentials: withCredentials
};

@@ -56,0 +58,0 @@

@@ -22,2 +22,10 @@ /*!

function generateState() {
return util.genRandomString(64);
}
function generateNonce() {
return util.genRandomString(64);
}
function isToken(obj) {

@@ -163,2 +171,3 @@ if (obj &&

var userinfoUrl = util.removeTrailingSlash(options.userinfoUrl) || sdk.options.userinfoUrl;
var tokenUrl = util.removeTrailingSlash(options.tokenUrl) || sdk.options.tokenUrl;

@@ -207,3 +216,5 @@ // If an issuer exists but it's not a url, assume it's an authServerId

userinfoUrl = userinfoUrl || issuer + '/v1/userinfo';
// Shared resource server tokenUrls look like:
// https://example.okta.com/oauth2/aus8aus76q8iphupD0h7/v1/token
tokenUrl = tokenUrl || issuer + '/v1/token';
// Normally looks like:

@@ -218,2 +229,5 @@ // https://example.okta.com

userinfoUrl = userinfoUrl || issuer + '/oauth2/v1/userinfo';
// Normal tokenUrls look like:
// https://example.okta.com/oauth2/v1/token
tokenUrl = tokenUrl || issuer + '/oauth2/v1/token';
}

@@ -224,3 +238,4 @@

authorizeUrl: authorizeUrl,
userinfoUrl: userinfoUrl
userinfoUrl: userinfoUrl,
tokenUrl: tokenUrl
};

@@ -259,2 +274,4 @@ }

module.exports = {
generateState: generateState,
generateNonce: generateNonce,
getWellKnown: getWellKnown,

@@ -261,0 +278,0 @@ getKey: getKey,

@@ -18,2 +18,6 @@ /*!

function storageBuilder(webstorage, storageName) {
if (typeof storageName !== 'string' || !storageName.length) {
throw new AuthSdkError('"storageName" is required');
}
function getStorage() {

@@ -20,0 +24,0 @@ var storageString = webstorage.getItem(storageName);

@@ -24,2 +24,3 @@ /*!

var cookies = require('./browser/browserStorage').storage;
var pkce = require('./pkce');

@@ -131,6 +132,37 @@ function decodeToken(token) {

function exchangeCodeForToken(sdk, oauthParams, authorizationCode, urls) {
// PKCE authorization_code flow
// Retrieve saved values and build oauthParams for call to /token
var meta = pkce.loadMeta(sdk);
var getTokenParams = {
clientId: oauthParams.clientId,
grantType: 'authorization_code',
authorizationCode: authorizationCode,
codeVerifier: meta.codeVerifier,
redirectUri: meta.redirectUri
};
return pkce.getToken(sdk, getTokenParams, urls)
.then(function(res) {
validateResponse(res, getTokenParams);
return res;
})
.fin(function() {
pkce.clearMeta(sdk);
});
}
function validateResponse(res, oauthParams) {
if (res['error'] || res['error_description']) {
throw new OAuthError(res['error'], res['error_description']);
}
if (res.state !== oauthParams.state) {
throw new AuthSdkError('OAuth flow response state doesn\'t match request state');
}
}
function handleOAuthResponse(sdk, oauthParams, res, urls) {
urls = urls || {};
var tokenTypes = oauthParams.responseType;
var responseType = oauthParams.responseType;
var scopes = util.clone(oauthParams.scopes);

@@ -141,10 +173,12 @@ var clientId = oauthParams.clientId || sdk.options.clientId;

.then(function() {
if (res['error'] || res['error_description']) {
throw new OAuthError(res['error'], res['error_description']);
}
validateResponse(res, oauthParams);
if (res.state !== oauthParams.state) {
throw new AuthSdkError('OAuth flow response state doesn\'t match request state');
// We do not support "hybrid" scenarios where the response includes both a code and a token.
// If the response contains a code it is used immediately to obtain new tokens.
if (res['code']) {
responseType = ['token', 'id_token']; // what we expect the code to provide us
return exchangeCodeForToken(sdk, oauthParams, res['code'], urls);
}
return res;
}).then(function(res) {
var tokenDict = {};

@@ -163,8 +197,2 @@

if (res['code']) {
tokenDict['code'] = {
authorizationCode: res['code']
};
}
if (res['id_token']) {

@@ -186,6 +214,9 @@ var jwt = sdk.token.decode(res['id_token']);

issuer: urls.issuer,
nonce: oauthParams.nonce,
ignoreSignature: oauthParams.ignoreSignature
nonce: oauthParams.nonce
};
if (oauthParams.ignoreSignature !== undefined) {
validationParams.ignoreSignature = oauthParams.ignoreSignature;
}
return verifyToken(sdk, idToken, validationParams)

@@ -201,12 +232,18 @@ .then(function() {

.then(function(tokenDict) {
if (!Array.isArray(tokenTypes)) {
return tokenDict[tokenTypes];
if (!Array.isArray(responseType)) {
return tokenDict[responseType];
}
if (!tokenDict['token'] && !tokenDict['id_token']) {
throw new AuthSdkError('Unable to parse OAuth flow response');
}
// Validate response against tokenTypes
var validateTokenTypes = ['token', 'id_token'];
validateTokenTypes.filter(function(key) {
return (responseType.indexOf(key) !== -1);
}).forEach(function(key) {
if (!tokenDict[key]) {
throw new AuthSdkError('Unable to parse OAuth flow response: ' + key + ' was not returned.');
}
});
// Create token array in the order of the responseType array
return tokenTypes.map(function(item) {
return responseType.map(function(item) {
return tokenDict[item];

@@ -220,9 +257,12 @@ });

var grantType = sdk.options.grantType || 'implicit';
var responseType = grantType === 'authorization_code' ? 'code' : 'id_token';
var defaults = {
grantType: grantType,
clientId: sdk.options.clientId,
redirectUri: sdk.options.redirectUri || window.location.href,
responseType: 'id_token',
responseType: responseType,
responseMode: 'okta_post_message',
state: util.genRandomString(64),
nonce: util.genRandomString(64),
state: oauthUtil.generateState(),
nonce: oauthUtil.generateNonce(),
scopes: ['openid', 'email'],

@@ -232,2 +272,7 @@ ignoreSignature: sdk.options.ignoreSignature

util.extend(defaults, oauthOptions);
if (defaults.grantType === 'authorization_code' && !defaults.codeChallengeMethod) {
defaults.codeChallengeMethod = pkce.DEFAULT_CODE_CHALLENGE_METHOD;
}
return defaults;

@@ -258,3 +303,5 @@ }

'idp': oauthParams.idp,
'max_age': oauthParams.maxAge
'max_age': oauthParams.maxAge,
'code_challenge': oauthParams.codeChallenge,
'code_challenge_method': oauthParams.codeChallengeMethod
});

@@ -335,128 +382,131 @@

// Default OAuth query params
var oauthParams = getDefaultOAuthParams(sdk, oauthOptions);
return prepareOauthParams(sdk, oauthOptions)
.then(function(oauthParams) {
// Start overriding any options that don't make sense
var sessionTokenOverrides = {
prompt: 'none',
responseMode: 'okta_post_message',
display: null
};
// Start overriding any options that don't make sense
var sessionTokenOverrides = {
prompt: 'none',
responseMode: 'okta_post_message',
display: null
};
var idpOverrides = {
display: 'popup'
};
var idpOverrides = {
display: 'popup'
};
if (oauthOptions.sessionToken) {
util.extend(oauthParams, sessionTokenOverrides);
} else if (oauthOptions.idp) {
util.extend(oauthParams, idpOverrides);
}
if (oauthOptions.sessionToken) {
util.extend(oauthParams, sessionTokenOverrides);
} else if (oauthOptions.idp) {
util.extend(oauthParams, idpOverrides);
}
// Use the query params to build the authorize url
var requestUrl,
urls;
try {
// Get authorizeUrl and issuer
urls = oauthUtil.getOAuthUrls(sdk, oauthParams, options);
requestUrl = urls.authorizeUrl + buildAuthorizeParams(oauthParams);
} catch (e) {
return Q.reject(e);
}
// Use the query params to build the authorize url
var requestUrl,
endpoint,
urls;
try {
// Get authorizeUrl and issuer
urls = oauthUtil.getOAuthUrls(sdk, oauthParams, options);
endpoint = oauthOptions.codeVerifier ? urls.tokenUrl : urls.authorizeUrl;
requestUrl = endpoint + buildAuthorizeParams(oauthParams);
} catch (e) {
return Q.reject(e);
}
// Determine the flow type
var flowType;
if (oauthParams.sessionToken || oauthParams.display === null) {
flowType = 'IFRAME';
} else if (oauthParams.display === 'popup') {
flowType = 'POPUP';
} else {
flowType = 'IMPLICIT';
}
// Determine the flow type
var flowType;
if (oauthParams.sessionToken || oauthParams.display === null) {
flowType = 'IFRAME';
} else if (oauthParams.display === 'popup') {
flowType = 'POPUP';
} else {
flowType = 'IMPLICIT';
}
function getOrigin(url) {
/* eslint-disable-next-line no-useless-escape */
var originRegex = /^(https?\:\/\/)?([^:\/?#]*(?:\:[0-9]+)?)/;
return originRegex.exec(url)[0];
}
function getOrigin(url) {
/* eslint-disable-next-line no-useless-escape */
var originRegex = /^(https?\:\/\/)?([^:\/?#]*(?:\:[0-9]+)?)/;
return originRegex.exec(url)[0];
}
// Execute the flow type
switch (flowType) {
case 'IFRAME':
var iframePromise = addPostMessageListener(sdk, options.timeout, oauthParams.state);
var iframeEl = oauthUtil.loadFrame(requestUrl);
return iframePromise
.then(function(res) {
return handleOAuthResponse(sdk, oauthParams, res, urls);
})
.fin(function() {
if (document.body.contains(iframeEl)) {
iframeEl.parentElement.removeChild(iframeEl);
}
});
// Execute the flow type
switch (flowType) {
case 'IFRAME':
var iframePromise = addPostMessageListener(sdk, options.timeout, oauthParams.state);
var iframeEl = oauthUtil.loadFrame(requestUrl);
return iframePromise
.then(function(res) {
return handleOAuthResponse(sdk, oauthParams, res, urls);
})
.fin(function() {
if (document.body.contains(iframeEl)) {
iframeEl.parentElement.removeChild(iframeEl);
}
});
case 'POPUP': // eslint-disable-line no-case-declarations
var popupPromise;
case 'POPUP': // eslint-disable-line no-case-declarations
var popupPromise;
// Add listener on postMessage before window creation, so
// postMessage isn't triggered before we're listening
if (oauthParams.responseMode === 'okta_post_message') {
if (!sdk.features.isPopupPostMessageSupported()) {
return Q.reject(new AuthSdkError('This browser doesn\'t have full postMessage support'));
// Add listener on postMessage before window creation, so
// postMessage isn't triggered before we're listening
if (oauthParams.responseMode === 'okta_post_message') {
if (!sdk.features.isPopupPostMessageSupported()) {
return Q.reject(new AuthSdkError('This browser doesn\'t have full postMessage support'));
}
popupPromise = addPostMessageListener(sdk, options.timeout, oauthParams.state);
}
popupPromise = addPostMessageListener(sdk, options.timeout, oauthParams.state);
}
// Create the window
var windowOptions = {
popupTitle: options.popupTitle
};
var windowEl = oauthUtil.loadPopup(requestUrl, windowOptions);
// Create the window
var windowOptions = {
popupTitle: options.popupTitle
};
var windowEl = oauthUtil.loadPopup(requestUrl, windowOptions);
// Poll until we get a valid hash fragment
if (oauthParams.responseMode === 'fragment') {
var windowOrigin = getOrigin(sdk.idToken.authorize._getLocationHref());
var redirectUriOrigin = getOrigin(oauthParams.redirectUri);
if (windowOrigin !== redirectUriOrigin) {
return Q.reject(new AuthSdkError('Using fragment, the redirectUri origin (' + redirectUriOrigin +
') must match the origin of this page (' + windowOrigin + ')'));
// Poll until we get a valid hash fragment
if (oauthParams.responseMode === 'fragment') {
var windowOrigin = getOrigin(sdk.idToken.authorize._getLocationHref());
var redirectUriOrigin = getOrigin(oauthParams.redirectUri);
if (windowOrigin !== redirectUriOrigin) {
return Q.reject(new AuthSdkError('Using fragment, the redirectUri origin (' + redirectUriOrigin +
') must match the origin of this page (' + windowOrigin + ')'));
}
popupPromise = addFragmentListener(sdk, windowEl, options.timeout);
}
popupPromise = addFragmentListener(sdk, windowEl, options.timeout);
}
// Both postMessage and fragment require a poll to see if the popup closed
var popupDeferred = Q.defer();
/* eslint-disable-next-line no-case-declarations, no-inner-declarations */
function hasClosed(win) {
if (win.closed) {
popupDeferred.reject(new AuthSdkError('Unable to parse OAuth flow response'));
// Both postMessage and fragment require a poll to see if the popup closed
var popupDeferred = Q.defer();
/* eslint-disable-next-line no-case-declarations, no-inner-declarations */
function hasClosed(win) {
if (win.closed) {
popupDeferred.reject(new AuthSdkError('Unable to parse OAuth flow response'));
}
}
}
var closePoller = setInterval(function() {
hasClosed(windowEl);
}, 500);
var closePoller = setInterval(function() {
hasClosed(windowEl);
}, 500);
// Proxy the promise results into the deferred
popupPromise
.then(function(res) {
popupDeferred.resolve(res);
})
.fail(function(err) {
popupDeferred.reject(err);
});
return popupDeferred.promise
// Proxy the promise results into the deferred
popupPromise
.then(function(res) {
return handleOAuthResponse(sdk, oauthParams, res, urls);
popupDeferred.resolve(res);
})
.fin(function() {
if (!windowEl.closed) {
clearInterval(closePoller);
windowEl.close();
}
.fail(function(err) {
popupDeferred.reject(err);
});
default:
return Q.reject(new AuthSdkError('The full page redirect flow is not supported'));
}
return popupDeferred.promise
.then(function(res) {
return handleOAuthResponse(sdk, oauthParams, res, urls);
})
.fin(function() {
if (!windowEl.closed) {
clearInterval(closePoller);
windowEl.close();
}
});
default:
return Q.reject(new AuthSdkError('The full page redirect flow is not supported'));
}
});
}

@@ -477,3 +527,4 @@

util.extend(oauthParams, {
display: 'popup'
display: 'popup',
responseMode: 'okta_post_message'
});

@@ -483,46 +534,87 @@ return getToken(sdk, oauthParams, options);

function getWithRedirect(sdk, oauthOptions, options) {
oauthOptions = util.clone(oauthOptions) || {};
function prepareOauthParams(sdk, oauthOptions) {
var oauthParams = getDefaultOAuthParams(sdk, oauthOptions);
// If the user didn't specify a responseMode
if (!oauthOptions.responseMode) {
// And it's only an auth code request (responseType could be an array)
var respType = oauthParams.responseType;
if (respType.indexOf('code') !== -1 &&
(util.isString(respType) || (Array.isArray(respType) && respType.length === 1))) {
// Default the responseMode to query
util.extend(oauthParams, {
responseMode: 'query'
});
// Otherwise, default to fragment
} else {
util.extend(oauthParams, {
responseMode: 'fragment'
});
var responseType = oauthParams.responseType;
if (typeof responseType === 'string') {
responseType = [responseType];
}
if (oauthParams.grantType !== 'authorization_code') {
if (responseType.includes('code')) {
return Q.reject(new AuthSdkError('When responseType is "code", grantType should be "authorization_code"'));
}
return Q.resolve(oauthParams);
}
var urls = oauthUtil.getOAuthUrls(sdk, oauthParams, options);
var requestUrl = urls.authorizeUrl + buildAuthorizeParams(oauthParams);
if (!sdk.features.isPKCESupported()) {
return Q.reject(new AuthSdkError('This browser doesn\'t support PKCE'));
}
// Set session cookie to store the oauthParams
cookies.set(config.REDIRECT_OAUTH_PARAMS_COOKIE_NAME, JSON.stringify({
responseType: oauthParams.responseType,
state: oauthParams.state,
nonce: oauthParams.nonce,
scopes: oauthParams.scopes,
clientId: oauthParams.clientId,
urls: urls,
ignoreSignature: oauthParams.ignoreSignature
}));
if (responseType.length !== 1 || responseType[0] !== 'code') {
return Q.reject(new AuthSdkError('When grantType is "authorization_code", responseType should be "code"'));
}
// Set nonce cookie for servers to validate nonce in id_token
cookies.set(config.REDIRECT_NONCE_COOKIE_NAME, oauthParams.nonce);
return oauthUtil.getWellKnown(sdk, null)
.then(function(res) {
var methods = res['code_challenge_methods_supported'] || [];
if (methods.indexOf(oauthParams.codeChallengeMethod) === -1) {
throw new AuthSdkError('Invalid code_challenge_method');
}
})
.then(function() {
// PKCE authorization_code flow
var codeVerifier = pkce.generateVerifier(oauthParams.codeVerifier);
// Set state cookie for servers to validate state
cookies.set(config.REDIRECT_STATE_COOKIE_NAME, oauthParams.state);
// We will need these values after redirect when we call /token
var meta = {
codeVerifier: codeVerifier,
redirectUri: oauthParams.redirectUri
};
pkce.saveMeta(sdk, meta);
sdk.token.getWithRedirect._setLocation(requestUrl);
return pkce.computeChallenge(codeVerifier);
})
.then(function(codeChallenge) {
// Clone/copy the params. Set codeChallenge and responseType for authorization_code
var clonedParams = util.clone(oauthParams) || {};
util.extend(clonedParams, oauthParams, {
codeChallenge: codeChallenge,
});
return clonedParams;
});
}
function getWithRedirect(sdk, oauthOptions, options) {
oauthOptions = util.clone(oauthOptions) || {};
if (!oauthOptions.responseMode) {
oauthOptions.responseMode = 'fragment';
}
return prepareOauthParams(sdk, oauthOptions)
.then(function(oauthParams) {
var urls = oauthUtil.getOAuthUrls(sdk, oauthParams, options);
var requestUrl = urls.authorizeUrl + buildAuthorizeParams(oauthParams);
// Set session cookie to store the oauthParams
cookies.set(config.REDIRECT_OAUTH_PARAMS_COOKIE_NAME, JSON.stringify({
responseType: oauthParams.responseType,
state: oauthParams.state,
nonce: oauthParams.nonce,
scopes: oauthParams.scopes,
clientId: oauthParams.clientId,
urls: urls,
ignoreSignature: oauthParams.ignoreSignature
}));
// Set nonce cookie for servers to validate nonce in id_token
cookies.set(config.REDIRECT_NONCE_COOKIE_NAME, oauthParams.nonce);
// Set state cookie for servers to validate state
cookies.set(config.REDIRECT_STATE_COOKIE_NAME, oauthParams.state);
sdk.token.getWithRedirect._setLocation(requestUrl);
});
}
function renewToken(sdk, token) {

@@ -535,3 +627,5 @@ if (!oauthUtil.isToken(token)) {

var responseType;
if (token.accessToken) {
if (sdk.options.grantType === 'authorization_code') {
responseType = 'code';
} else if (token.accessToken) {
responseType = 'token';

@@ -541,2 +635,3 @@ } else {

}
return sdk.token.getWithoutPrompt({

@@ -640,3 +735,5 @@ responseType: responseType,

getUserInfo: getUserInfo,
verifyToken: verifyToken
verifyToken: verifyToken,
handleOAuthResponse: handleOAuthResponse,
prepareOauthParams: prepareOauthParams
};

@@ -143,14 +143,26 @@ /*!

tokenMgmtRef.renewPromise[key] = sdk.token.renew(token)
.then(function(freshToken) {
if (!get(storage, key)) {
// It is possible to enter a state where the tokens have been cleared
// after a renewal request was triggered. To ensure we do not store a
// renewed token, we verify the promise key doesn't exist and return.
return;
.then(function(freshTokens) {
// We may receive more tokens than we requested
var map = {};
if (freshTokens instanceof Array === false) {
freshTokens = [freshTokens];
}
add(sdk, tokenMgmtRef, storage, key, freshToken);
tokenMgmtRef.emitter.emit('renewed', key, freshToken, token);
freshTokens.forEach(function(freshToken) {
var inferredKey = freshToken.idToken ? 'idToken' : freshToken.accessToken ? 'accessToken' : key;
map[inferredKey] = freshToken;
var oldToken = get(storage, inferredKey);
if (!oldToken) {
// It is possible to enter a state where the tokens have been cleared
// after a renewal request was triggered. To ensure we do not store a
// renewed token, we verify the promise key doesn't exist and return.
return;
}
add(sdk, tokenMgmtRef, storage, inferredKey, freshToken);
tokenMgmtRef.emitter.emit('renewed', inferredKey, freshToken, oldToken);
});
// Remove existing promise key
delete tokenMgmtRef.renewPromise[key];
return freshToken;
return map[key]; // return the specific token requested
})

@@ -157,0 +169,0 @@ .fail(function(err) {

@@ -15,2 +15,14 @@ /*!

// converts a string to base64 (url/filename safe variant)
util.stringToBase64Url = function(str) {
var b64 = btoa(str);
return util.base64ToBase64Url(b64);
};
// converts a standard base64-encoded string to a "url/filename safe" variant
util.base64ToBase64Url = function(b64) {
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
};
// converts a "url/filename safe" base64 string to a "standard" base64 string
util.base64UrlToBase64 = function(b64u) {

@@ -17,0 +29,0 @@ return b64u.replace(/-/g, '+').replace(/_/g, '/');

{
"name": "@okta/okta-auth-js",
"description": "The Okta Auth SDK",
"version": "2.5.0",
"version": "2.6.0",
"homepage": "https://github.com/okta/okta-auth-js",

@@ -19,3 +19,4 @@ "license": "Apache-2.0",

"lint:report": "eslint -f checkstyle -o build2/reports/lint/eslint-checkstyle-result.xml .",
"test": "yarn test:browser && yarn test:server",
"test": "yarn test:karma && yarn test:browser && yarn test:server",
"test:karma": "karma start --single-run",
"test:browser": "jest --config ./jest.browser.js",

@@ -25,3 +26,7 @@ "test:server": "jest --config ./jest.server.js",

"build": "node ./writeConfig.js && webpack --config webpack.config.js",
"prepublish": "yarn build"
"prepare": "yarn build",
"install:app": "yarn --cwd test/app install",
"start:app": "yarn --cwd test/app start",
"prestart": "yarn install:app",
"start": "yarn start:app"
},

@@ -47,2 +52,4 @@ "author": "Okta",

"eslint": "5.6.1",
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine-ajax": "^4.0.0",
"jest": "^23.6.0",

@@ -52,4 +59,11 @@ "jest-junit": "^5.0.0",

"json-loader": "0.5.4",
"karma": "^4.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage-istanbul-reporter": "^2.0.5",
"karma-jasmine": "^2.0.1",
"karma-jquery": "^0.2.3",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^3.0.5",
"lodash": "4.17.11",
"webpack": "1.13.0"
"webpack": "^3.0.0"
},

@@ -66,3 +80,4 @@ "okta-auth-js": {

"TOKEN_STORAGE_NAME": "okta-token-storage",
"CACHE_STORAGE_NAME": "okta-cache-storage"
"CACHE_STORAGE_NAME": "okta-cache-storage",
"PKCE_STORAGE_NAME": "okta-pkce-storage"
},

@@ -73,5 +88,5 @@ "jest-junit": {

"okta": {
"commitSha": "0e998a8e66fc90a25b97028dcebc275b83b67ccc",
"fullVersion": "2.5.0-20190415215843-0e998a8"
"commitSha": "f5f930605fda763c22ef2bf5c03ba4d83ad4ad56",
"fullVersion": "2.6.0-20190603213603-f5f9306"
}
}

@@ -165,4 +165,6 @@ [<img src="https://devforum.okta.com/uploads/oktadev/original/1X/bf54a16b5fda189e4ad2706fb57cbb7a1e5b8deb.png" align="right" width="256px"/>](https://devforum.okta.com/)

| `redirectUri` | The url that is redirected to when using `token.getWithRedirect`. This must be pre-registered as part of client registration. If no `redirectUri` is provided, defaults to the current origin. |
| `grantType` | Specify `grantType` for this Application. Supported types are `implicit` and `authorization_code`. Defaults to `implicit` |
| `authorizeUrl` | Specify a custom authorizeUrl to perform the OIDC flow. Defaults to the issuer plus "/v1/authorize". |
| `userinfoUrl` | Specify a custom userinfoUrl. Defaults to the issuer plus "/v1/userinfo". |
| `tokenUrl` | Specify a custom tokenUrl. Defaults to the issuer plus "/v1/token". |
| `ignoreSignature` | ID token signatures are validated by default when `token.getWithoutPrompt`, `token.getWithPopup`, `token.getWithRedirect`, and `token.verify` are called. To disable ID token signature validation for these methods, set this value to `true`. |

@@ -195,2 +197,24 @@ | | This option should be used only for browser support and testing purposes. |

##### PKCE OAuth 2.0 flow
By default the `implicit` OAuth flow will be used. It is widely supported by most browsers. PKCE is a newer flow which is more secure, but does require certain capabilities from the browser.
To use PKCE flow, set `grantType` to `authorization_code` in your config.
```javascript
var config = {
grantType: 'authorization_code',
// other config
issuer: 'https://{yourOktaDomain}/oauth2/default',
};
var authClient = new OktaAuth(config);
```
If the user's browser does not support PKCE, an exception will be thrown. You can test if a browser supports PKCE before construction with this static method:
`OktaAuth.features.isPKCESupported()`
### Optional configuration options

@@ -217,3 +241,4 @@

// },
// data: postBodyData
// data: postBodyData,
// withCredentials: true|false,
// }

@@ -492,3 +517,3 @@ return Promise.resolve(/* a raw XMLHttpRequest response */);

![State Model Diagram](https://raw.githubusercontent.com/okta/okta.github.io/source/_source/_assets/img/auth-state-model.png "State Model Diagram")
![State Model Diagram](https://developer.okta.com/img/auth-state-model.png "State Model Diagram")

@@ -1374,3 +1399,3 @@ #### Common methods

| `responseMode` | Specify how the authorization response should be returned. You will generally not need to set this unless you want to override the default values for `token.getWithRedirect`. See [Parameter Details](https://developer.okta.com/docs/api/resources/oidc#parameter-details) for a list of available modes. |
| `responseType` | Specify the [response type](https://developer.okta.com/docs/api/resources/oidc#request-parameters) for OIDC authentication. Defaults to `id_token`. |
| `responseType` | Specify the [response type](https://developer.okta.com/docs/api/resources/oidc#request-parameters) for OIDC authentication. The default value is based on the configured `grantType`. If `grantType` is `implicit` (the default setting), `responseType` will have a default value of `id_token`. If `grantType` is `authorization_code`, the default value will be `code`. |
| | Use an array if specifying multiple response types - in this case, the response will contain both an ID Token and an Access Token. `responseType: ['id_token', 'token']` |

@@ -1383,2 +1408,3 @@ | `scopes` | Specify what information to make available in the returned `id_token` or `access_token`. For OIDC, you must include `openid` as one of the scopes. Defaults to `['openid', 'email']`. For a list of available scopes, see [Scopes and Claims](https://developer.okta.com/docs/api/resources/oidc#access-token-scopes-and-claims). |

##### Example

@@ -1454,4 +1480,9 @@

Parses the access or ID Tokens from the url after a successful authentication redirect. If an ID token is present, it will be [verified and validated](https://github.com/okta/okta-auth-js/blob/master/lib/token.js#L186-L190) before available for use.
Parses the authorization code, access, or ID Tokens from the URL after a successful authentication redirect.
If an authorization code is present, it will be exchanged for token(s) by posting to the `tokenUrl` endpoint.
The ID token will be [verified and validated](https://github.com/okta/okta-auth-js/blob/master/lib/token.js#L186-L190) before available for use.
```javascript

@@ -1728,5 +1759,10 @@ authClient.token.parseFromUrl()

| `yarn build` | Build the SDK with a sourcemap |
| `yarn test` | Run unit tests using Jest |
| `yarn test` | Run unit tests |
| `yarn lint` | Run eslint linting |
| `yarn start` | Start internal test app |
#### Test App
Implements a simple SPA application to demonstrate functionality and provide for manual testing. [See here for more information](test/app/README.md).
## Contributing

@@ -1733,0 +1769,0 @@

@@ -16,2 +16,3 @@ /*!

function reqwestRequest(method, url, args) {
// TODO: support content-type and withCredentials
var r = reqwest({

@@ -22,3 +23,3 @@ url: url,

data: JSON.stringify(args.data),
withCredentials: true
withCredentials: args.withCredentials
})

@@ -25,0 +26,0 @@ .then(function() {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc