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 1.17.0 to 2.0.0

CHANGELOG.md

13

jquery/index.js

@@ -0,2 +1,15 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
var jqueryRequest = require('./jqueryRequest');
module.exports = require('../lib/clientBuilder')(jqueryRequest);

2

jquery/jqueryRequest.js
/*!
* Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -4,0 +4,0 @@ *

/*!
* Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -37,8 +37,15 @@ *

if (!args.url) {
throw new AuthSdkError('No url passed to constructor. ' +
var url = args.url;
if (!url) {
var isUrlRegex = new RegExp('^http?s?://.+');
if (args.issuer && isUrlRegex.test(args.issuer)) {
// Infer the URL from the issuer URL, omitting the /oauth2/{authServerId}
url = args.issuer.split('/oauth2/')[0];
} else {
throw new AuthSdkError('No url passed to constructor. ' +
'Required usage: new OktaAuth({url: "https://sample.okta.com"})');
}
}
if (args.url.indexOf('-admin.') !== -1) {
if (url.indexOf('-admin.') !== -1) {
throw new AuthSdkError('URL passed to constructor contains "-admin" in subdomain. ' +

@@ -49,3 +56,3 @@ 'Required usage: new OktaAuth({url: "https://dev-12345.okta.com})');

this.options = {
url: util.removeTrailingSlash(args.url),
url: util.removeTrailingSlash(url),
clientId: args.clientId,

@@ -76,2 +83,6 @@ issuer: util.removeTrailingSlash(args.issuer),

// Give the developer the ability to disable token signature
// validation.
this.options.ignoreSignature = !!args.ignoreSignature;
sdk.session = {

@@ -96,16 +107,11 @@ close: util.bind(session.closeSession, null, sdk),

// This is exposed so we can mock window.location.href in our tests
sdk.idToken = {
authorize: util.deprecateWrap('Use token.getWithoutPrompt, token.getWithPopup, or token.getWithRedirect ' +
'instead of idToken.authorize.', util.bind(token.getToken, null, sdk)),
verify: util.deprecateWrap('Use token.verify instead of idToken.verify', util.bind(token.verifyIdToken, null, sdk)),
refresh: util.deprecateWrap('Use token.refresh instead of idToken.refresh',
util.bind(token.refreshIdToken, null, sdk)),
decode: util.deprecateWrap('Use token.decode instead of idToken.decode', token.decodeToken)
authorize: {
_getLocationHref: function() {
return window.location.href;
}
}
};
// This is exposed so we can mock window.location.href in our tests
sdk.idToken.authorize._getLocationHref = function() {
return window.location.href;
};
sdk.token = {

@@ -117,3 +123,3 @@ getWithoutPrompt: util.bind(token.getWithoutPrompt, null, sdk),

decode: token.decodeToken,
refresh: util.bind(token.refreshToken, null, sdk),
renew: util.bind(token.renewToken, null, sdk),
getUserInfo: util.bind(token.getUserInfo, null, sdk),

@@ -120,0 +126,0 @@ verify: util.bind(token.verifyToken, null, sdk)

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

"CACHE_STORAGE_NAME": "okta-cache-storage",
"SDK_VERSION": "1.16.0"
"SDK_VERSION": "2.0.0"
};

@@ -1,37 +0,39 @@

var util = require('./util');
/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
var Cookies = require('js-cookie');
function setCookie(name, value, expiresAt) {
var expiresText = '';
if (expiresAt) {
expiresText = ' expires=' + util.isoToUTCString(expiresAt) + ';';
var cookieOptions = {
path: '/'
};
// eslint-disable-next-line no-extra-boolean-cast
if (!!(Date.parse(expiresAt))) {
// Expires value can be converted to a Date object.
//
// If the 'expiresAt' value is not provided, or the value cannot be
// parsed as a Date object, the cookie will set as a session cookie.
cookieOptions.expires = new Date(expiresAt);
}
var cookieText = name + '=' + value + '; path=/;' + expiresText;
setCookie._setDocumentCookie(cookieText);
return cookieText;
Cookies.set(name, value, cookieOptions);
return getCookie(name);
}
// Exposed for testing
setCookie._setDocumentCookie = function(cookieText) {
document.cookie = cookieText;
};
function getCookie(name) {
var pattern = new RegExp(name + '=([^;]*)'),
matched = getCookie._getDocumentCookie().match(pattern);
if (matched) {
var cookie = matched[1];
return cookie;
}
return Cookies.get(name);
}
// Exposed for testing
getCookie._getDocumentCookie = function() {
return document.cookie;
};
function deleteCookie(name) {
setCookie(name, '', '1970-01-01T00:00:00Z');
return Cookies.remove(name, { path: '/' });
}

@@ -38,0 +40,0 @@

/*!
* Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -4,0 +4,0 @@ *

/*!
* Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -4,0 +4,0 @@ *

/*!
* Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -4,0 +4,0 @@ *

/*!
* Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -4,0 +4,0 @@ *

/*!
* Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -4,0 +4,0 @@ *

@@ -0,1 +1,14 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
/* eslint-disable complexity */

@@ -2,0 +15,0 @@ var util = require('./util');

@@ -0,2 +1,15 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
// This exists to use reqwest for http requests by default
module.exports = require('../reqwest');

@@ -1,2 +0,2 @@

Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -3,0 +3,0 @@

@@ -0,1 +1,14 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
/* eslint-disable complexity, max-statements */

@@ -104,3 +117,7 @@ var http = require('./http');

function validateClaims(sdk, claims, aud, iss, nonce) {
function validateClaims(sdk, claims, validationParams) {
var aud = validationParams.clientId;
var iss = validationParams.issuer;
var nonce = validationParams.nonce;
if (!claims || !iss || !aud) {

@@ -107,0 +124,0 @@ throw new AuthSdkError('The jwt, iss, and aud arguments are all required');

@@ -0,1 +1,14 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
var util = require('./util');

@@ -2,0 +15,0 @@ var http = require('./http');

@@ -0,1 +1,14 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
var AuthSdkError = require('./errors/AuthSdkError');

@@ -2,0 +15,0 @@

@@ -0,1 +1,14 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
var cookies = require('./cookies');

@@ -2,0 +15,0 @@ var storageBuilder = require('./storageBuilder');

@@ -0,1 +1,14 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
/* eslint-disable complexity, max-statements */

@@ -29,69 +42,3 @@ var http = require('./http');

function verifyIdToken(sdk, idToken, options) {
options = options || {};
if (!sdk.features.isTokenVerifySupported()) {
return Q.reject(new AuthSdkError('This browser doesn\'t support crypto.subtle'));
}
function isExpired(jwtExp) {
var expirationTime;
if (options.expirationTime || options.expirationTime === 0) {
expirationTime = options.expirationTime;
} else {
expirationTime = Math.floor(Date.now()/1000);
}
if (jwtExp &&
jwtExp > expirationTime) {
return true;
}
}
function hasAudience(jwtAudience) {
if (!options.audience) {
return true;
}
var audiences = Array.isArray(options.audience) ? options.audience : [options.audience];
var jwtAudiences = Array.isArray(jwtAudience) ? jwtAudience : [jwtAudience];
var ai = audiences.length;
while (ai--) {
var aud = audiences[ai];
if (jwtAudiences.indexOf(aud) !== -1) {
return true;
}
}
}
return oauthUtil.getWellKnown(sdk)
.then(function(res) {
return http.get(sdk, res['jwks_uri']);
})
.then(function(res) {
var key = res.keys[0];
return sdkCrypto.verifyToken(idToken, key);
})
.then(function(res) {
if (!res) {
return false;
}
var jwt = sdk.token.decode(idToken);
if (isExpired(jwt.payload.exp)) {
return false;
}
if (!hasAudience(jwt.payload.aud)) {
return false;
}
if (options.issuer &&
options.issuer !== jwt.payload.iss) {
return false;
}
return true;
});
}
function verifyToken(sdk, token, nonce, ignoreSignature) {
function verifyToken(sdk, token, validationParams) {
return new Q()

@@ -105,8 +52,16 @@ .then(function() {

var validationOptions = {
clientId: sdk.options.clientId,
issuer: sdk.options.issuer || sdk.options.url,
ignoreSignature: sdk.options.ignoreSignature
};
util.extend(validationOptions, validationParams);
// Standard claim validation
oauthUtil.validateClaims(sdk, jwt.payload, token.clientId, token.issuer, nonce);
oauthUtil.validateClaims(sdk, jwt.payload, validationOptions);
// If the browser doesn't support native crypto or we choose not
// If the browser doesn't support native crypto or we choose not
// to verify the signature, bail early
if (ignoreSignature || !sdk.features.isTokenVerifySupported()) {
if (validationOptions.ignoreSignature == true || !sdk.features.isTokenVerifySupported()) {
return token;

@@ -128,9 +83,2 @@ }

function refreshIdToken(sdk, options) {
options = options || {};
options.display = null;
options.prompt = 'none';
return getToken(sdk, options);
}
function addPostMessageListener(sdk, timeout, state) {

@@ -164,3 +112,3 @@ var deferred = Q.defer();

there's no other way to determine that the popup is in
another domain. When we try to access a window on another
another domain. When we try to access a window on another
domain, an error is thrown.

@@ -204,3 +152,3 @@ */

var tokenDict = {};
if (res['access_token']) {

@@ -236,3 +184,10 @@ tokenDict['token'] = {

return verifyToken(sdk, idToken, oauthParams.nonce, true)
var validationParams = {
clientId: clientId,
issuer: urls.issuer,
nonce: oauthParams.nonce,
ignoreSignature: oauthParams.ignoreSignature
};
return verifyToken(sdk, idToken, validationParams)
.then(function() {

@@ -265,8 +220,2 @@ tokenDict['id_token'] = idToken;

if (oauthOptions.scope) {
util.deprecate('The param "scope" is equivalent to "scopes". Use "scopes" instead.');
oauthOptions.scopes = oauthOptions.scope;
delete oauthOptions.scope;
}
var defaults = {

@@ -279,3 +228,4 @@ clientId: sdk.options.clientId,

nonce: util.genRandomString(64),
scopes: ['openid', 'email']
scopes: ['openid', 'email'],
ignoreSignature: sdk.options.ignoreSignature
};

@@ -332,7 +282,7 @@ util.extend(defaults, oauthOptions);

* Retrieve an idToken from an Okta or a third party idp
*
*
* Two main flows:
*
* 1) Exchange a sessionToken for a token
*
*
* Required:

@@ -549,3 +499,3 @@ * clientId: passed via the OktaAuth constructor or into getToken

}
var urls = oauthUtil.getOAuthUrls(sdk, oauthParams, options);

@@ -560,2 +510,3 @@ var requestUrl = urls.authorizeUrl + buildAuthorizeParams(oauthParams);

scopes: oauthParams.scopes,
clientId: oauthParams.clientId,
urls: urls

@@ -573,5 +524,5 @@ }));

function refreshToken(sdk, token) {
function renewToken(sdk, token) {
if (!oauthUtil.isToken(token)) {
return Q.reject(new AuthSdkError('Refresh must be passed a token with ' +
return Q.reject(new AuthSdkError('Renew must be passed a token with ' +
'an array of scopes and an accessToken or idToken'));

@@ -614,6 +565,11 @@ }

var oauthParamsCookie = cookies.getCookie(config.REDIRECT_OAUTH_PARAMS_COOKIE_NAME);
if (!hash || !oauthParamsCookie) {
if (!hash) {
return Q.reject(new AuthSdkError('Unable to parse a token from the url'));
}
var oauthParamsCookie = cookies.getCookie(config.REDIRECT_OAUTH_PARAMS_COOKIE_NAME);
if (!oauthParamsCookie) {
return Q.reject(new AuthSdkError('Unable to retrieve OAuth redirect params cookie'));
}
try {

@@ -625,3 +581,3 @@ var oauthParams = JSON.parse(oauthParamsCookie);

} catch(e) {
return Q.reject(new AuthSdkError('Unable to parse the ' +
return Q.reject(new AuthSdkError('Unable to parse the ' +
config.REDIRECT_OAUTH_PARAMS_COOKIE_NAME + ' cookie: ' + e.message));

@@ -673,8 +629,6 @@ }

parseFromUrl: parseFromUrl,
refreshIdToken: refreshIdToken,
decodeToken: decodeToken,
verifyIdToken: verifyIdToken,
refreshToken: refreshToken,
renewToken: renewToken,
getUserInfo: getUserInfo,
verifyToken: verifyToken
};

@@ -0,1 +1,14 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
/* eslint complexity:[0,8] max-statements:[0,21] */

@@ -14,41 +27,40 @@ var util = require('./util');

function clearRefreshTimeout(tokenMgmtRef, key) {
clearTimeout(tokenMgmtRef.refreshTimeouts[key]);
delete tokenMgmtRef.refreshTimeouts[key];
function emitError(tokenMgmtRef, error) {
tokenMgmtRef.emitter.emit('error', error);
}
function clearRefreshTimeoutAll(tokenMgmtRef) {
var refreshTimeouts = tokenMgmtRef.refreshTimeouts;
for(var key in refreshTimeouts) {
if (!refreshTimeouts.hasOwnProperty(key)) {
function clearExpireEventTimeout(tokenMgmtRef, key) {
clearTimeout(tokenMgmtRef.expireTimeouts[key]);
delete tokenMgmtRef.expireTimeouts[key];
// Remove the renew promise (if it exists)
delete tokenMgmtRef.renewPromise[key];
}
function clearExpireEventTimeoutAll(tokenMgmtRef) {
var expireTimeouts = tokenMgmtRef.expireTimeouts;
for (var key in expireTimeouts) {
if (!expireTimeouts.hasOwnProperty(key)) {
continue;
}
clearRefreshTimeout(tokenMgmtRef, key);
clearExpireEventTimeout(tokenMgmtRef, key);
}
tokenMgmtRef.refreshTimeouts = {};
}
function setRefreshTimeout(sdk, tokenMgmtRef, storage, key, token) {
var refreshWait = (token.expiresAt * 1000) - Date.now();
if (refreshWait < 0) {
// Already expired
refreshWait = 0;
}
var refreshTimeout = setTimeout(function() {
if (tokenMgmtRef.autoRefresh) {
return refresh(sdk, tokenMgmtRef, storage, key);
} else if (token.expiresAt * 1000 <= Date.now()) {
remove(tokenMgmtRef, storage, key);
emitExpired(tokenMgmtRef, key, token);
}
}, refreshWait);
function setExpireEventTimeout(sdk, tokenMgmtRef, key, token) {
var clockSkew = sdk.options.maxClockSkew * 1000;
var expireEventWait = (token.expiresAt * 1000) - (Date.now() - clockSkew);
// Clear any existing timeout
clearRefreshTimeout(tokenMgmtRef, key);
clearExpireEventTimeout(tokenMgmtRef, key);
var expireEventTimeout = setTimeout(function() {
emitExpired(tokenMgmtRef, key, token);
}, expireEventWait);
// Add a new timeout
tokenMgmtRef.refreshTimeouts[key] = refreshTimeout;
tokenMgmtRef.expireTimeouts[key] = expireEventTimeout;
}
function setRefreshTimeoutAll(sdk, tokenMgmtRef, storage) {
function setExpireEventTimeoutAll(sdk, tokenMgmtRef, storage) {
try {

@@ -59,3 +71,3 @@ var tokenStorage = storage.getStorage();

// because there are no listeners yet
tokenMgmtRef.emitter.emit('error', e);
emitError(tokenMgmtRef, e);
return;

@@ -69,3 +81,3 @@ }

var token = tokenStorage[key];
setRefreshTimeout(sdk, tokenMgmtRef, storage, key, token);
setExpireEventTimeout(sdk, tokenMgmtRef, key, token);
}

@@ -84,3 +96,3 @@ }

storage.setStorage(tokenStorage);
setRefreshTimeout(sdk, tokenMgmtRef, storage, key, token);
setExpireEventTimeout(sdk, tokenMgmtRef, key, token);
}

@@ -93,5 +105,21 @@

function getAsync(sdk, tokenMgmtRef, storage, key) {
return Q.Promise(function(resolve) {
var token = get(storage, key);
var clockSkew = sdk.options.maxClockSkew * 1000;
if (!token || (token.expiresAt * 1000 - clockSkew) > Date.now()) {
resolve(token);
}
var tokenPromise = tokenMgmtRef.autoRenew
? renew(sdk, tokenMgmtRef, storage, key)
: remove(tokenMgmtRef, storage, key);
resolve(tokenPromise);
});
}
function remove(tokenMgmtRef, storage, key) {
// Clear any listener for this token
clearRefreshTimeout(tokenMgmtRef, key);
clearExpireEventTimeout(tokenMgmtRef, key);

@@ -104,3 +132,3 @@ // Remove it from storage

function refresh(sdk, tokenMgmtRef, storage, key) {
function renew(sdk, tokenMgmtRef, storage, key) {
try {

@@ -115,22 +143,35 @@ var token = get(storage, key);

// Remove existing autoRefresh timeout for this key
clearRefreshTimeout(tokenMgmtRef, key);
// Remove existing autoRenew timeout for this key
clearExpireEventTimeout(tokenMgmtRef, key);
return sdk.token.refresh(token)
.then(function(freshToken) {
add(sdk, tokenMgmtRef, storage, key, freshToken);
tokenMgmtRef.emitter.emit('refreshed', key, freshToken, token);
return freshToken;
})
.fail(function(err) {
if (err.name === 'OAuthError') {
remove(tokenMgmtRef, storage, key);
emitExpired(tokenMgmtRef, key, token);
}
throw err;
});
// Store the renew promise state, to avoid renewing again
if (!tokenMgmtRef.renewPromise[key]) {
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;
}
add(sdk, tokenMgmtRef, storage, key, freshToken);
tokenMgmtRef.emitter.emit('renewed', key, freshToken, token);
// Remove existing promise key
delete tokenMgmtRef.renewPromise[key];
return freshToken;
})
.fail(function(err) {
if (err.name === 'OAuthError') {
remove(tokenMgmtRef, storage, key);
emitError(tokenMgmtRef, err);
}
throw err;
});
}
return tokenMgmtRef.renewPromise[key];
}
function clear(tokenMgmtRef, storage) {
clearRefreshTimeoutAll(tokenMgmtRef);
clearExpireEventTimeoutAll(tokenMgmtRef);
storage.clearStorage();

@@ -142,4 +183,4 @@ }

options.storage = options.storage || 'localStorage';
if (!options.autoRefresh && options.autoRefresh !== false) {
options.autoRefresh = true;
if (!options.autoRenew && options.autoRenew !== false) {
options.autoRenew = true;
}

@@ -174,17 +215,18 @@

emitter: new Emitter(),
autoRefresh: options.autoRefresh,
refreshTimeouts: {}
autoRenew: options.autoRenew,
expireTimeouts: {},
renewPromise: {}
};
this.add = util.bind(add, this, sdk, tokenMgmtRef, storage);
this.get = util.bind(get, this, storage);
this.get = util.bind(getAsync, this, sdk, tokenMgmtRef, storage);
this.remove = util.bind(remove, this, tokenMgmtRef, storage);
this.clear = util.bind(clear, this, tokenMgmtRef, storage);
this.refresh = util.bind(refresh, this, sdk, tokenMgmtRef, storage);
this.renew = util.bind(renew, this, sdk, tokenMgmtRef, storage);
this.on = util.bind(tokenMgmtRef.emitter.on, tokenMgmtRef.emitter);
this.off = util.bind(tokenMgmtRef.emitter.off, tokenMgmtRef.emitter);
setRefreshTimeoutAll(sdk, tokenMgmtRef, storage);
setExpireEventTimeoutAll(sdk, tokenMgmtRef, storage);
}
module.exports = TokenManager;

@@ -0,1 +1,14 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
/* eslint-disable complexity, max-statements */

@@ -2,0 +15,0 @@ var http = require('./http');

/*!
* Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -188,3 +188,3 @@ *

}
var link = util.clone(obj._links[linkName]);

@@ -239,6 +239,8 @@

}
if (path.slice(-1) === '/') {
return path.slice(0, -1);
// Remove any whitespace before or after string
var trimmed = path.replace(/^\s+|\s+$/gm,'');
if (trimmed.slice(-1) === '/') {
return trimmed.slice(0, -1);
}
return path;
return trimmed;
};

@@ -245,0 +247,0 @@

@@ -0,1 +1,14 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
module.exports = require('../lib/clientBuilder')();
{
"name": "@okta/okta-auth-js",
"description": "The Okta Auth SDK",
"version": "1.17.0",
"version": "2.0.0",
"homepage": "https://github.com/okta/okta-auth-js",

@@ -33,2 +33,3 @@ "license": "Apache-2.0",

"Base64": "0.3.0",
"js-cookie": "2.2.0",
"q": "1.4.1",

@@ -67,5 +68,5 @@ "reqwest": "2.0.5",

"okta": {
"commitSha": "f872b346a13badfad795cab104a2716f17938977",
"fullVersion": "1.17.0-20180427163300-f872b34"
"commitSha": "ff1dec7d5b4d3c35778ae438bbd1fce0462ede95",
"fullVersion": "2.0.0-20180814231838-ff1dec7"
}
}

@@ -1,102 +0,58 @@

<!-- START GITHUB ONLY -->
[<img src="https://devforum.okta.com/uploads/oktadev/original/1X/bf54a16b5fda189e4ad2706fb57cbb7a1e5b8deb.png" align="right" width="256px"/>](https://devforum.okta.com/)
[![Support](https://img.shields.io/badge/support-developer%20forum-blue.svg)](https://devforum.okta.com)
[![Build Status](https://travis-ci.org/okta/okta-auth-js.svg?branch=master)](https://travis-ci.org/okta/okta-auth-js)
[![npm version](https://img.shields.io/npm/v/@okta/okta-auth-js.svg?style=flat-square)](https://www.npmjs.com/package/@okta/okta-auth-js)
<!-- END GITHUB ONLY -->
Introduction
============
# Okta Auth JavaScript SDK
The Okta Auth SDK builds on top of our [Authentication API](http://developer.okta.com/docs/api/resources/authn.html) and [OAuth 2.0 API](http://developer.okta.com/docs/api/resources/oidc.html) to enable you to create a fully branded sign-in experience using JavaScript.
* [Release status](#release-status)
* [Need help?](#need-help)
* [Getting started](#getting-started)
* [Usage guide](#usage-guide)
* [Configuration reference](#configuration-reference)
* [API Reference](#api-reference)
* [Building the SDK](#building-the-sdk)
* [Contributing](#contributing)
<!-- START GITHUB ONLY -->
For an overview of the client's features and authentication flows, check out [our developer docs](http://developer.okta.com/docs/guides/okta_auth_sdk.html).
The Okta Auth JavaScript SDK builds on top of our [Authentication API](https://developer.okta.com/docs/api/resources/authn) and [OAuth 2.0 API](https://developer.okta.com/docs/api/resources/oidc) to enable you to create a fully branded sign-in experience using JavaScript.
Read our [contributing guidelines](./CONTRIBUTING.md) if you wish to contribute.
You can learn more on the [Okta + JavaScript][lang-landing] page in our documentation.
# Table of Contents
## Release status
* [Install](#install)
* [Using the Okta CDN](#using-the-okta-cdn)
* [Using the npm module](#using-the-npm-module)
* [API](#api)
* [OktaAuth](#new-oktaauthconfig)
* [signIn](#signinoptions)
* [signOut](#signout)
* [forgotPassword](#forgotpasswordoptions)
* [unlockAccount](#unlockaccountoptions)
* [verifyRecoveryToken](#verifyrecoverytokenoptions)
* [webfinger](#webfingeroptions)
* [fingerprint](#fingerprintoptions)
* [tx.resume](#txresume)
* [tx.exists](#txexists)
* [transaction.status](#transactionstatus)
* [LOCKED_OUT](#locked_out)
* [PASSWORD_EXPIRED](#password_expired)
* [PASSWORD_RESET](#password_reset)
* [PASSWORD_WARN](#password_warn)
* [RECOVERY](#recovery)
* [RECOVERY_CHALLENGE](#recovery_challenge)
* [MFA_ENROLL](#mfa_enroll)
* [Enroll Factor](#enroll-factor)
* [MFA_ENROLL_ACTIVATE](#mfa_enroll_activate)
* [MFA_REQUIRED](#mfa_required)
* [MFA_CHALLENGE](#mfa_challenge)
* [SUCCESS](#success)
* [session.setCookieAndRedirect](#sessionsetcookieandredirectsessiontoken-redirecturi)
* [session.exists](#sessionexists)
* [session.get](#sessionget)
* [session.refresh](#sessionrefresh)
* [token.getWithoutPrompt](#tokengetwithoutpromptoauthoptions)
* [token.getWithPopup](#tokengetwithpopupoauthoptions)
* [token.getWithRedirect](#tokengetwithredirectoptions)
* [token.parseFromUrl](#tokenparsefromurloptions)
* [token.decode](#tokendecodeidtokenstring)
* [token.refresh](#tokenrefreshtokentorefresh)
* [token.getUserInfo](#tokengetuserinfoaccesstokenobject)
* [token.verify](#tokenverifyidtokenobject)
* [tokenManager.add](#tokenmanageraddkey-token)
* [tokenManager.get](#tokenmanagergetkey)
* [tokenManager.remove](#tokenmanagerremovekey)
* [tokenManager.clear](#tokenmanagerclear)
* [tokenManager.refresh](#tokenmanagerrefreshkey)
* [tokenManager.on](#tokenmanagerontokenevent-callback-context)
* [tokenManager.off](#tokenmanageroffevent-callback)
* [OpenId Connect Options](#openid-connect-options)
* [Client Configuration](#client-configuration)
* [Developing the Okta Auth Client](#developing-the-okta-auth-client)
* [Building the Client](#building-the-client)
* [Build and Test Commands](#build-and-test-commands)
<!-- END GITHUB ONLY -->
This library uses semantic versioning and follows Okta's [library version policy](https://developer.okta.com/code/library-versions/).
# Install
:heavy_check_mark: The current stable major version series is: `2.x`
You can include Okta Auth JS in your project either directly from the Okta CDN, or by packaging it with your app via our npm package, [@okta/okta-auth-js](https://www.npmjs.com/package/@okta/okta-auth-js).
| Version | Status |
| ------- | -------------------------------- |
| `2.x` | :heavy_check_mark: Stable |
| `1.x` | :warning: Retiring on 2019-05-31 |
| `0.x` | :x: Retired |
## Using the Okta CDN
The latest release can always be found on the [releases page][github-releases].
Loading our assets directly from the CDN is a good choice if you want an easy way to get started with okta-auth-js, and don't already have an existing build process that leverages [npm](https://www.npmjs.com/) for external dependencies.
## Need help?
To use the CDN, include links to the JS and CSS files in your HTML:
If you run into problems using the SDK, you can:
```html
<!-- Latest CDN production Javascript: 1.11.0 -->
<script
src="https://ok1static.oktacdn.com/assets/js/sdk/okta-auth-js/1.11.0/okta-auth-js.min.js"
type="text/javascript"></script>
```
* Ask questions on the [Okta Developer Forums][devforum]
* Post [issues][github-issues] here on GitHub (for code errors)
The `okta-auth-js.min.js` file will expose a global `OktaAuth` object. Use it to bootstrap the client:
## Getting started
```javascript
var authClient = new OktaAuth({/* configOptions */});
```
Installing the Authentication SDK is simple. You can include it in your project via our npm package, [@okta/okta-auth-js](https://www.npmjs.com/package/@okta/okta-auth-js).
## Using the npm module
You'll also need:
* An Okta account, called an _organization_ (sign up for a free [developer organization](https://developer.okta.com/signup) if you need one)
### Using the npm module
Using our npm module is a good choice if:
- You have a build system in place where you manage dependencies with npm.
* You have a build system in place where you manage dependencies with npm.
* You do not want to load scripts directly from third party sites.
- You do not want to load scripts directly from third party sites.
To install [@okta/okta-auth-js](https://www.npmjs.com/package/@okta/okta-auth-js):

@@ -106,9 +62,7 @@

# Run this command in your project root folder.
[project-root-folder]$ npm install @okta/okta-auth-js --save
npm install @okta/okta-auth-js --save
```
After running `npm install`:
After running `npm install`, the minified auth client will be installed to `node_modules/@okta/okta-auth-js/dist`. You can copy the `dist` contents to a publicly hosted directory. However, if you're using a bundler like [Webpack](https://webpack.github.io/) or [Browserify](http://browserify.org/), you can simply import the module using CommonJS.
The minified auth client will be installed to `node_modules/@okta/okta-auth-js/dist`. You can copy the `dist` contents to a publicly hosted directory. However, if you're using a bundler like [Webpack](https://webpack.github.io/) or [Browserify](http://browserify.org/), you can simply import the module using CommonJS.
```javascript

@@ -119,23 +73,195 @@ var OktaAuth = require('@okta/okta-auth-js');

# API
If you're using a bundler like webpack or browserify, we have implementations for jquery and reqwest included. To use them, import the SDK like this:
## new OktaAuth(config)
```javascript
// reqwest
var OktaAuth = require('@okta/okta-auth-js/reqwest');
Creates a new instance of the Okta Auth Client with the provided options. The client has many [config options](#client-configuration). The only required option to get started is `url`, the base url for your Okta domain.
// jquery
var OktaAuth = require('@okta/okta-auth-js/jquery');
```
- `config` - Options that are used to configure the client
## Usage guide
For an overview of the client's features and authentication flows, check out [our developer docs](https://developer.okta.com/docs/guides/okta_auth_sdk). There, you will learn how to use the Auth SDK on a simple static page to:
* Retrieve and store an OpenID Connect (OIDC) token
* Get an Okta session
You can also browse the full [API reference documentation](#api-reference).
## Configuration reference
If you are using this SDK to implement an OIDC flow, the only required configuration option is `issuer`:
```javascript
var authClient = new OktaAuth({url: 'https://acme.okta.com'});
var config = {
issuer: 'https://{yourOktaDomain}/oauth2/default'
};
var authClient = new OktaAuth(config);
```
## signIn(options)
If you’re using this SDK only for communicating with the [Authentication API](https://developer.okta.com/docs/api/resources/authn), you instead need to set the `url` for your Okta Domain:
The goal of an authentication flow is to [set an Okta session cookie on the user's browser](http://developer.okta.com/use_cases/authentication/session_cookie#retrieving-a-session-cookie-by-visiting-a-session-redirect-link) or [retrieve an `id_token` or `access_token`](http://developer.okta.com/use_cases/authentication/session_cookie#retrieving-a-session-cookie-via-openid-connect-authorization-endpoint). The flow is started using `signIn`.
```javascript
var config = {
// The URL for your Okta organization
url: 'https://{yourOktaDomain}'
};
- `username` - User’s non-qualified short-name (e.g. dade.murphy) or unique fully-qualified login (e.g dade.murphy@example.com)
- `password` - The password of the user
- `sendFingerprint` - Enabling this will send a `X-Device-Fingerprint` header. Defaults to `false`
var authClient = new OktaAuth(config);
```
### [OpenID Connect](https://developer.okta.com/docs/api/resources/oidc) options
These configuration options can be included when instantiating Okta Auth JS (`new OktaAuth(config)`) or in `token.getWithoutPrompt`, `token.getWithPopup`, or `token.getWithRedirect` (unless noted otherwise). If included in both, the value passed in the method takes priority.
#### The `tokenManager`
**Important:** This configuration option can be included **only** when instantiating Okta Auth JS.
Specify the type of storage for tokens. Defaults to [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) and will fall back to [sessionStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage), and/or [cookie](https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie) if not the previous type is not available.
```javascript
var config = {
url: 'https://{yourOktaDomain}',
tokenManager: {
storage: 'sessionStorage'
}
};
var authClient = new OktaAuth(config);
```
By default, the `tokenManager` will attempt to renew expired tokens. When an expired token is requested by the `tokenManager.get()` method, a renewal request is executed to update the token. If you wish to manually control token renewal, set `autoRenew` to false to disable this feature. You can listen to [`expired`](#tokenmanageronevent-callback-context) events to know when the token has expired.
```javascript
tokenManager: {
autoRenew: false
}
```
#### Additional Options
| Option | Description |
| -------------- | ------------ |
| `issuer` | Specify a custom issuer to perform the OIDC flow. Defaults to the base url parameter if not provided. |
| `clientId` | Client Id pre-registered with Okta for the OIDC authentication flow. |
| `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. |
| `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". |
| `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`. |
| | This option should be used only for browser support and testing purposes. |
##### Example Client
```javascript
var config = {
url: 'https://{yourOktaDomain}',
// Optional config
issuer: 'https://{yourOktaDomain}/oauth2/default',
clientId: 'GHtf9iJdr60A9IYrR0jw',
redirectUri: 'https://acme.com/oauth2/callback/home',
// Override the default authorize and userinfo URLs
authorizeUrl: 'https://{yourOktaDomain}/oauth2/default/v1/authorize',
userinfoUrl: 'https://{yourOktaDomain}/oauth2/default/v1/userinfo',
// TokenManager config
tokenManager: {
storage: 'sessionStorage'
}
};
var authClient = new OktaAuth(config);
```
### Optional configuration options
#### `ajaxRequest`
The ajax request implementation. By default, this is implemented using [reqwest](https://github.com/ded/reqwest). To provide your own request library, implement the following interface:
1. Must accept:
* method (http method)
* url (target url)
* args (object containing headers and data)
2. Must return a Promise that resolves with a raw XMLHttpRequest response
```javascript
var config = {
url: 'https://{yourOktaDomain}',
ajaxRequest: function(method, url, args) {
// args is in the form:
// {
// headers: {
// headerName: headerValue
// },
// data: postBodyData
// }
return Promise.resolve(/* a raw XMLHttpRequest response */);
}
}
```
## API Reference
* [signIn](#signinoptions)
* [signOut](#signout)
* [forgotPassword](#forgotpasswordoptions)
* [unlockAccount](#unlockaccountoptions)
* [verifyRecoveryToken](#verifyrecoverytokenoptions)
* [webfinger](#webfingeroptions)
* [fingerprint](#fingerprintoptions)
* [tx.resume](#txresume)
* [tx.exists](#txexists)
* [transaction.status](#transactionstatus)
* [LOCKED_OUT](#locked_out)
* [PASSWORD_EXPIRED](#password_expired)
* [PASSWORD_RESET](#password_reset)
* [PASSWORD_WARN](#password_warn)
* [RECOVERY](#recovery)
* [RECOVERY_CHALLENGE](#recovery_challenge)
* [MFA_ENROLL](#mfa_enroll)
* [MFA_ENROLL_ACTIVATE](#mfa_enroll_activate)
* [MFA_REQUIRED](#mfa_required)
* [MFA_CHALLENGE](#mfa_challenge)
* [SUCCESS](#success)
* [session](#session)
* [session.setCookieAndRedirect](#sessionsetcookieandredirectsessiontoken-redirecturi)
* [session.exists](#sessionexists)
* [session.get](#sessionget)
* [session.refresh](#sessionrefresh)
* [token](#token)
* [token.getWithoutPrompt](#tokengetwithoutpromptoauthoptions)
* [token.getWithPopup](#tokengetwithpopupoauthoptions)
* [token.getWithRedirect](#tokengetwithredirectoptions)
* [token.parseFromUrl](#tokenparsefromurloptions)
* [token.decode](#tokendecodeidtokenstring)
* [token.renew](#tokenrenewtokentorenew)
* [token.getUserInfo](#tokengetuserinfoaccesstokenobject)
* [token.verify](#tokenverifyidtokenobject)
* [tokenManager](#tokenmanager)
* [tokenManager.add](#tokenmanageraddkey-token)
* [tokenManager.get](#tokenmanagergetkey)
* [tokenManager.remove](#tokenmanagerremovekey)
* [tokenManager.clear](#tokenmanagerclear)
* [tokenManager.renew](#tokenmanagerrenewkey)
* [tokenManager.on](#tokenmanageronevent-callback-context)
* [tokenManager.off](#tokenmanageroffevent-callback)
------
### `signIn(options)`
The goal of an authentication flow is to [set an Okta session cookie on the user's browser](https://developer.okta.com/use_cases/authentication/session_cookie#retrieving-a-session-cookie-by-visiting-a-session-redirect-link) or [retrieve an `id_token` or `access_token`](https://developer.okta.com/use_cases/authentication/session_cookie#retrieving-a-session-cookie-via-openid-connect-authorization-endpoint). The flow is started using `signIn`.
* `username` - User’s non-qualified short-name (e.g. dade.murphy) or unique fully-qualified login (e.g dade.murphy@example.com)
* `password` - The password of the user
* `sendFingerprint` - Enabling this will send a `X-Device-Fingerprint` header. Defaults to `false`
```javascript
authClient.signIn({

@@ -157,5 +283,5 @@ username: 'some-username',

## signOut()
### `signOut()`
Signs the user out of their current Okta [session](http://developer.okta.com/docs/api/resources/sessions.html#example).
Signs the user out of their current Okta [session](https://developer.okta.com/docs/api/resources/sessions#example).

@@ -172,9 +298,9 @@ ```javascript

## [forgotPassword(options)](http://developer.okta.com/docs/api/resources/authn.html#forgot-password)
### `forgotPassword(options)`
Starts a new password recovery transaction for a given user and issues a recovery token that can be used to reset a user’s password.
Starts a [new password recovery transaction](https://developer.okta.com/docs/api/resources/authn#forgot-password) for a given user and issues a recovery token that can be used to reset a user’s password.
- `username` - User’s non-qualified short-name (e.g. dade.murphy) or unique fully-qualified login (e.g dade.murphy@example.com)
- `factorType` - Recovery factor to use for primary authentication. Supported options are `SMS`, `EMAIL`, or `CALL`
- `relayState` - Optional state value that is persisted for the lifetime of the recovery transaction
* `username` - User’s non-qualified short-name (e.g. dade.murphy) or unique fully-qualified login (e.g dade.murphy@example.com)
* `factorType` - Recovery factor to use for primary authentication. Supported options are `SMS`, `EMAIL`, or `CALL`
* `relayState` - Optional state value that is persisted for the lifetime of the recovery transaction

@@ -203,9 +329,9 @@ ```javascript

## [unlockAccount(options)](http://developer.okta.com/docs/api/resources/authn.html#unlock-account)
### `unlockAccount(options)`
Starts a new unlock recovery transaction for a given user and issues a recovery token that can be used to unlock a user’s account.
Starts a [new unlock recovery transaction](https://developer.okta.com/docs/api/resources/authn#unlock-account) for a given user and issues a recovery token that can be used to unlock a user’s account.
- `username` - User’s non-qualified short-name (e.g. dade.murphy) or unique fully-qualified login (e.g dade.murphy@example.com)
- `factorType` - Recovery factor to use for primary authentication. Supported options are `SMS`, `EMAIL`, or `CALL`
- `relayState` - Optional state value that is persisted for the lifetime of the recovery transaction
* `username` - User’s non-qualified short-name (e.g. dade.murphy) or unique fully-qualified login (e.g dade.murphy@example.com)
* `factorType` - Recovery factor to use for primary authentication. Supported options are `SMS`, `EMAIL`, or `CALL`
* `relayState` - Optional state value that is persisted for the lifetime of the recovery transaction

@@ -234,7 +360,7 @@ ```javascript

## [verifyRecoveryToken(options)](http://developer.okta.com/docs/api/resources/authn.html#verify-recovery-token)
### `verifyRecoveryToken(options)`
Validates a recovery token that was distributed to the end-user to continue the recovery transaction.
Validates a recovery token that was distributed to the end-user to continue the [recovery transaction](https://developer.okta.com/docs/api/resources/authn#verify-recovery-token).
- `recoveryToken` - Recovery token that was distributed to end-user via an out-of-band mechanism such as email
* `recoveryToken` - Recovery token that was distributed to end-user via an out-of-band mechanism such as email

@@ -257,9 +383,9 @@ ```javascript

## [webfinger(options)](https://tools.ietf.org/html/rfc7033)
### `webfinger(options)`
Calls the Webfinger API and gets a response.
Calls the [Webfinger](https://tools.ietf.org/html/rfc7033) API and gets a response.
- `resource` - URI that identifies the entity whose information is sought, currently only acct scheme is supported (e.g acct:dade.murphy@example.com)
- `rel` - Optional parameter to request only a subset of the information that would otherwise be returned without the "rel" parameter
- `requestContext` - Optional parameter that provides Webfinger the context of that which the user is trying to access, such as the path of an app
* `resource` - URI that identifies the entity whose information is sought, currently only acct scheme is supported (e.g acct:dade.murphy@example.com)
* `rel` - Optional parameter to request only a subset of the information that would otherwise be returned without the "rel" parameter
* `requestContext` - Optional parameter that provides Webfinger the context of that which the user is trying to access, such as the path of an app

@@ -280,7 +406,7 @@ ```javascript

## [fingerprint(options)]
### `fingerprint(options)`
Creates a browser fingerprint.
- `timeout` - Time in ms until the operation times out. Defaults to 15000.
* `timeout` - Time in ms until the operation times out. Defaults to `15000`.

@@ -297,3 +423,3 @@ ```javascript

## tx.resume()
### `tx.resume()`

@@ -315,3 +441,3 @@ Resumes an in-progress **transaction**. This is useful if a user navigates away from the login page before authentication is complete.

## tx.exists()
### `tx.exists()`

@@ -321,3 +447,3 @@ Check for a **transaction** to be resumed. This is synchronous and returns `true` or `false`.

```javascript
var exists = authClient.tx.exists()
var exists = authClient.tx.exists();
if (exists) {

@@ -330,14 +456,12 @@ console.log('a session exists');

## transaction.status
### `transaction.status`
When Auth Client methods resolve, they return a **transaction** object that encapsulates [the new state in the authentication flow](http://developer.okta.com/docs/api/resources/authn.html#transaction-model). This **transaction** contains metadata about the current state, and methods that can be used to progress to the next state.
When Auth Client methods resolve, they return a **transaction** object that encapsulates [the new state in the authentication flow](https://developer.okta.com/docs/api/resources/authn#transaction-model). This **transaction** contains metadata about the current state, and methods that can be used to progress to the next state.
![State Model Diagram](http://developer.okta.com/assets/img/auth-state-model.png "State Model Diagram")
![State Model Diagram](https://raw.githubusercontent.com/okta/okta.github.io/source/_source/_assets/img/auth-state-model.png "State Model Diagram")
Sample transactions and their methods:
#### Common methods
### Common methods
##### `cancel()`
#### cancel()
Terminates the current auth flow.

@@ -352,201 +476,212 @@

### [LOCKED_OUT](http://developer.okta.com/docs/api/resources/authn.html#show-lockout-failures)
##### `changePassword(options)`
The user account is locked; self-service unlock or admin unlock is required.
[Changes](https://developer.okta.com/docs/api/resources/authn#reset-password) a user's password.
* `oldPassword` - User’s current password that is expired
* `newPassword` - New password for user
```javascript
{
status: 'LOCKED_OUT',
unlock: function(options) { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
transaction.changePassword({
oldPassword: '0ldP4ssw0rd',
newPassword: 'N3wP4ssw0rd'
});
```
#### [unlock(options)](http://developer.okta.com/docs/api/resources/authn.html#unlock-account)
##### `resetPassword(options)`
- `username` - User’s non-qualified short-name (e.g. dade.murphy) or unique fully-qualified login (e.g dade.murphy@example.com)
- `factorType` - Recovery factor to use for primary authentication. Supported options are `SMS`, `EMAIL`, or `CALL`
- `relayState` - Optional state value that is persisted for the lifetime of the recovery transaction
[Reset](https://developer.okta.com/docs/api/resources/authn#reset-password) a user's password.
* `newPassword` - New password for user
```javascript
transaction.unlock({
username: 'dade.murphy@example.com',
factorType: 'EMAIL'
transaction.resetPassword({
newPassword: 'N3wP4ssw0rd'
});
```
#### [cancel()](#cancel)
##### `skip()`
### [PASSWORD_EXPIRED](http://developer.okta.com/docs/api/resources/authn.html#response-example-expired-password)
Ignore the warning and continue.
The user’s password was successfully validated but is expired.
```javascript
{
status: 'PASSWORD_EXPIRED',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
changePassword: function(options) { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
transaction.skip();
```
#### [changePassword(options)](http://developer.okta.com/docs/api/resources/authn.html#reset-password)
#### LOCKED_OUT
- `oldPassword` - User’s current password that is expired
- `newPassword` - New password for user
The user account is [locked](https://developer.okta.com/docs/api/resources/authn#show-lockout-failures); self-service unlock or admin unlock is required.
```javascript
transaction.changePassword({
oldPassword: '0ldP4ssw0rd',
newPassword: 'N3wP4ssw0rd'
});
```
<details>
<summary><b>Example Response</b></summary>
#### [cancel()](#cancel)
```javascript
{
status: 'LOCKED_OUT',
unlock: function(options) { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
### PASSWORD_RESET
</details>
The user successfully answered their recovery question and can set a new password.
##### `unlock(options)`
```javascript
{
status: 'PASSWORD_EXPIRED',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
resetPassword: function(options) { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
[Unlock](https://developer.okta.com/docs/api/resources/authn#unlock-account) the user account.
#### [resetPassword(options)](http://developer.okta.com/docs/api/resources/authn.html#reset-password)
* `username` - User’s non-qualified short-name (e.g. dade.murphy) or unique fully-qualified login (e.g dade.murphy@example.com)
* `factorType` - Recovery factor to use for primary authentication. Supported options are `SMS`, `EMAIL`, or `CALL`
* `relayState` - Optional state value that is persisted for the lifetime of the recovery transaction
- `newPassword` - New password for user
```javascript
transaction.resetPassword({
newPassword: 'N3wP4ssw0rd'
transaction.unlock({
username: 'dade.murphy@example.com',
factorType: 'EMAIL'
});
```
#### [cancel()](#cancel)
#### PASSWORD_EXPIRED
### PASSWORD_WARN
The user’s password was successfully validated but is [expired](https://developer.okta.com/docs/api/resources/authn#response-example-expired-password).
The user’s password was successfully validated but is about to expire and should be changed.
<details>
<summary><b>Example Response</b></summary>
```javascript
{
status: 'PASSWORD_WARN',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
policy: {
expiration:{
passwordExpireDays: 0
```javascript
{
status: 'PASSWORD_EXPIRED',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
complexity: {
minLength: 8,
minLowerCase: 1,
minUpperCase: 1,
minNumber: 1,
minSymbol: 0,
excludeUsername: true
changePassword: function(options) { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
</details>
#### PASSWORD_RESET
The user successfully answered their recovery question and can set a new password.
<details>
<summary><b>Example Response</b></summary>
```javascript
{
status: 'PASSWORD_EXPIRED',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
age:{
minAgeMinutes:0,
historyCount:0
}
},
changePassword: function(options) { /* returns another transaction */ },
skip: function() { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
resetPassword: function(options) { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
#### [changePassword(options)](http://developer.okta.com/docs/api/resources/authn.html#change-password)
</details>
- `oldPassword` - User’s current password that is about to expire
- `newPassword` - New password for user
#### PASSWORD_WARN
```javascript
transaction.changePassword({
oldPassword: '0ldP4ssw0rd',
newPassword: 'N3wP4ssw0rd'
});
```
The user’s password was successfully validated but is about to expire and should be changed.
#### skip()
<details>
<summary><b>Example Response</b></summary>
Ignore the warning and continue.
```javascript
{
status: 'PASSWORD_WARN',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
policy: {
expiration:{
passwordExpireDays: 0
},
complexity: {
minLength: 8,
minLowerCase: 1,
minUpperCase: 1,
minNumber: 1,
minSymbol: 0,
excludeUsername: true
},
age:{
minAgeMinutes:0,
historyCount:0
}
},
changePassword: function(options) { /* returns another transaction */ },
skip: function() { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
```javascript
transaction.skip();
```
</details>
#### [cancel()](#cancel)
#### RECOVERY
### RECOVERY
The user has requested a recovery token to reset their password or unlock their account.
```javascript
{
status: 'RECOVERY',
expiresAt: '2014-11-02T23:39:03.319Z',
recoveryType: 'PASSWORD', // or 'UNLOCK'
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
<details>
<summary><b>Example Response</b></summary>
```javascript
{
status: 'RECOVERY',
expiresAt: '2014-11-02T23:39:03.319Z',
recoveryType: 'PASSWORD', // or 'UNLOCK'
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
},
recovery_question: {
question: "Who's a major player in the cowboy scene?"
}
},
recovery_question: {
question: "Who's a major player in the cowboy scene?"
}
},
answer: function(options) { /* returns another transaction */ },
recovery: function(options) { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
answer: function(options) { /* returns another transaction */ },
recovery: function(options) { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
#### [answer(options)](http://developer.okta.com/docs/api/resources/authn.html#answer-recovery-question)
</details>
- `answer` - Answer to user’s recovery question
##### `answer(options)`
* `answer` - [Answer](https://developer.okta.com/docs/api/resources/authn#answer-recovery-question) to user’s recovery question
```javascript

@@ -558,5 +693,5 @@ transaction.answer({

#### [recovery(options)](http://developer.okta.com/docs/api/resources/authn.html#verify-recovery-token)
##### `recovery(options)`
- `recoveryToken` - Recovery token that was distributed to end-user via out-of-band mechanism such as email
* `recoveryToken` - [Recovery](https://developer.okta.com/docs/api/resources/authn#verify-recovery-token) token that was distributed to end-user via out-of-band mechanism such as email

@@ -569,35 +704,38 @@ ```javascript

#### [cancel()](#cancel)
#### RECOVERY_CHALLENGE
### RECOVERY_CHALLENGE
The user must verify the factor-specific recovery challenge.
```javascript
{
status: 'RECOVERY_CHALLENGE',
expiresAt: '2014-11-02T23:39:03.319Z',
recoveryType: 'PASSWORD', // or 'UNLOCK',
factorType: 'EMAIL', // or 'SMS'
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
verify: function(options) { /* returns another transaction */ },
resend: function() { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
<details>
<summary><b>Example Response</b></summary>
#### [verify(options)](http://developer.okta.com/docs/api/resources/authn.html#verify-sms-recovery-factor)
```javascript
{
status: 'RECOVERY_CHALLENGE',
expiresAt: '2014-11-02T23:39:03.319Z',
recoveryType: 'PASSWORD', // or 'UNLOCK',
factorType: 'EMAIL', // or 'SMS'
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
verify: function(options) { /* returns another transaction */ },
resend: function() { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
- `passCode` - OTP sent to device
</details>
##### `verify(options)`
* `passCode` - OTP sent to device for [verification](https://developer.okta.com/docs/api/resources/authn#verify-sms-recovery-factor)
```javascript

@@ -609,5 +747,5 @@ transaction.verify({

#### [resend()](http://developer.okta.com/docs/api/resources/authn.html#resend-sms-recovery-challenge)
##### `resend()`
Resend the recovery email or text.
[Resend](https://developer.okta.com/docs/api/resources/authn#resend-sms-recovery-challenge) the recovery email or text.

@@ -618,68 +756,67 @@ ```javascript

#### [cancel()](#cancel)
#### MFA_ENROLL
### MFA_ENROLL
When MFA is required, but a user isn’t enrolled in MFA, they must enroll in at least one factor.
```javascript
{
status: 'MFA_ENROLL',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
factors: [{
provider: 'OKTA',
factorType: 'question',
questions: function() { /* returns an array of possible questions */ },
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'OKTA',
factorType: 'sms',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'OKTA',
factorType: 'call',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'OKTA',
factorType: 'push',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'OKTA',
factorType: 'token:software:totp',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'GOOGLE',
factorType: 'token:software:totp',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'YUBICO',
factorType: 'token:hardware',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'RSA',
factorType: 'token',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'SYMANTEC',
factorType: 'token',
enroll: function(options) { /* returns another transaction */ }
}],
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
<details>
<summary><b>Example Response</b></summary>
#### [cancel()](#cancel)
```javascript
{
status: 'MFA_ENROLL',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ub0oNGTSWTBKOLGLNR',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
},
factors: [{
provider: 'OKTA',
factorType: 'question',
questions: function() { /* returns an array of possible questions */ },
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'OKTA',
factorType: 'sms',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'OKTA',
factorType: 'call',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'OKTA',
factorType: 'push',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'OKTA',
factorType: 'token:software:totp',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'GOOGLE',
factorType: 'token:software:totp',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'YUBICO',
factorType: 'token:hardware',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'RSA',
factorType: 'token',
enroll: function(options) { /* returns another transaction */ }
}, {
provider: 'SYMANTEC',
factorType: 'token',
enroll: function(options) { /* returns another transaction */ }
}],
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
#### Enroll Factor
</details>

@@ -692,5 +829,5 @@ To enroll in a factor, select one from the factors array, then use the following methods.

##### [questions()](http://developer.okta.com/docs/api/resources/factors.html#list-security-questions)
##### `questions()`
List the available questions for the question factorType.
List the available [questions](https://developer.okta.com/docs/api/resources/factors#list-security-questions) for the question factorType.

@@ -708,7 +845,7 @@ ```javascript

##### enroll(options)
##### `enroll(options)`
The enroll options depend on the desired factor.
###### [OKTA question](http://developer.okta.com/docs/api/resources/factors.html#enroll-okta-security-question-factor)
###### [OKTA question](https://developer.okta.com/docs/api/resources/factors#enroll-okta-security-question-factor)

@@ -728,3 +865,3 @@ ```javascript

###### [OKTA sms](http://developer.okta.com/docs/api/resources/factors.html#enroll-okta-sms-factor)
###### [OKTA sms](https://developer.okta.com/docs/api/resources/factors#enroll-okta-sms-factor)

@@ -746,3 +883,3 @@ ```javascript

###### [OKTA call](http://developer.okta.com/docs/api/resources/factors.html#enroll-okta-call-factor)
###### [OKTA call](https://developer.okta.com/docs/api/resources/factors#enroll-okta-call-factor)

@@ -764,3 +901,3 @@ ```javascript

###### [OKTA push](http://developer.okta.com/docs/api/resources/factors.html#enroll-okta-verify-push-factor)
###### [OKTA push](https://developer.okta.com/docs/api/resources/factors#enroll-okta-verify-push-factor)

@@ -777,3 +914,3 @@ ```javascript

###### [OKTA token:software:totp](http://developer.okta.com/docs/api/resources/factors.html#enroll-okta-verify-totp-factor)
###### [OKTA token:software:totp](https://developer.okta.com/docs/api/resources/factors#enroll-okta-verify-totp-factor)

@@ -790,3 +927,3 @@ ```javascript

###### [GOOGLE token:software:totp](http://developer.okta.com/docs/api/resources/factors.html#enroll-google-authenticator-factor)
###### [GOOGLE token:software:totp](https://developer.okta.com/docs/api/resources/factors#enroll-google-authenticator-factor)

@@ -803,3 +940,3 @@ ```javascript

###### [YUBICO token:hardware](http://developer.okta.com/docs/api/resources/factors.html#enroll-yubikey-factor)
###### [YUBICO token:hardware](https://developer.okta.com/docs/api/resources/factors#enroll-yubikey-factor)

@@ -816,3 +953,3 @@ ```javascript

###### [RSA token](http://developer.okta.com/docs/api/resources/factors.html#enroll-rsa-securid-factor)
###### [RSA token](https://developer.okta.com/docs/api/resources/factors#enroll-rsa-securid-factor)

@@ -832,3 +969,3 @@ ```javascript

###### [SYMANTEC token](http://developer.okta.com/docs/api/resources/factors.html#enroll-symantec-vip-factor)
###### [SYMANTEC token](https://developer.okta.com/docs/api/resources/factors#enroll-symantec-vip-factor)

@@ -849,45 +986,50 @@ ```javascript

### MFA_ENROLL_ACTIVATE
#### MFA_ENROLL_ACTIVATE
The user must activate the factor to complete enrollment.
```javascript
{
status: 'MFA_ENROLL_ACTIVATE',
expiresAt: '2014-11-02T23:39:03.319Z',
factorResult: 'WAITING', // or 'TIMEOUT',
user: {
id: '00ugti3kwafWJBRIY0g3',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
<details>
<summary><b>Example Response</b></summary>
```javascript
{
status: 'MFA_ENROLL_ACTIVATE',
expiresAt: '2014-11-02T23:39:03.319Z',
factorResult: 'WAITING', // or 'TIMEOUT',
user: {
id: '00ugti3kwafWJBRIY0g3',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
},
},
},
factor: {
id: 'opfh52xcuft3J4uZc0g3',
provider: 'OKTA',
factorType: 'push',
profile: {},
activation: {
expiresAt: '2015-04-01T15:57:32.000Z',
qrcode: {
href: 'https://acme.okta.com/api/v1/users/00ugti3kwafWJBRIY0g3/factors/opfh52xcuft3J4uZc0g3/qr/00fukNElRS_Tz6k-CFhg3pH4KO2dj2guhmaapXWbc4',
type: 'image/png'
factor: {
id: 'opfh52xcuft3J4uZc0g3',
provider: 'OKTA',
factorType: 'push',
profile: {},
activation: {
expiresAt: '2015-04-01T15:57:32.000Z',
qrcode: {
href: 'https://acme.okta.com/api/v1/users/00ugti3kwafWJBRIY0g3/factors/opfh52xcuft3J4uZc0g3/qr/00fukNElRS_Tz6k-CFhg3pH4KO2dj2guhmaapXWbc4',
type: 'image/png'
}
}
}
},
resend: function() { /* returns another transaction */ },
activate: function(options) { /* returns another transaction */ },
poll: function() { /* returns another transaction */ },
prev: function() { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
},
resend: function() { /* returns another transaction */ },
activate: function(options) { /* returns another transaction */ },
poll: function() { /* returns another transaction */ },
prev: function() { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
#### resend()
</details>
##### `resend()`
Send another OTP if user doesn’t receive the original activation SMS OTP.

@@ -899,5 +1041,5 @@

#### [activate(options)](http://developer.okta.com/docs/api/resources/authn.html#activate-sms-factor)
##### `activate(options)`
- `passCode` - OTP sent to device
* `passCode` - OTP- sent to device for [activation](https://developer.okta.com/docs/api/resources/authn#activate-sms-factor)

@@ -910,5 +1052,5 @@ ```javascript

#### [poll()](http://developer.okta.com/docs/api/resources/authn.html#activate-push-factor)
##### `poll()`
Poll until factorResult is not WAITING. Throws AuthPollStopError if prev, resend, or cancel is called.
[Poll](https://developer.okta.com/docs/api/resources/authn#activate-push-factor) until factorResult is not WAITING. Throws AuthPollStopError if prev, resend, or cancel is called.

@@ -919,5 +1061,5 @@ ```javascript

#### [prev()](http://developer.okta.com/docs/api/resources/authn.html#previous-transaction-state)
##### `prev()`
End current factor enrollment and return to `MFA_ENROLL`.
End current factor enrollment and [return to](https://developer.okta.com/docs/api/resources/authn#previous-transaction-state) `MFA_ENROLL`.

@@ -928,86 +1070,86 @@ ```javascript

#### [cancel()](#cancel)
#### MFA_REQUIRED
### MFA_REQUIRED
The user must provide additional verification with a previously enrolled factor.
<details>
<summary> <b>Example Response</b> </summary>
```javascript
{
status: 'MFA_REQUIRED',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ugti3kwafWJBRIY0g3',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
```javascript
{
status: 'MFA_REQUIRED',
expiresAt: '2014-11-02T23:39:03.319Z',
user: {
id: '00ugti3kwafWJBRIY0g3',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
},
},
},
factors: [{
id: 'ufsigasO4dVUPM5O40g3',
provider: 'OKTA',
factorType: 'question',
profile: {
question: 'disliked_food',
questionText: 'What is the food you least liked as a child?'
},
verify: function(options) { /* returns another transaction */ }
}, {
id: 'opfhw7v2OnxKpftO40g3',
provider: 'OKTA',
factorType: 'push',
profile: {
credentialId: 'isaac@example.org',
deviceType: 'SmartPhone_IPhone',
keys: [
{
kty: 'PKIX',
use: 'sig',
kid: 'default',
x5c: [
'MIIBIjANBgkqhkiG9w0BAQEFBAOCAQ8AMIIBCgKCAQEAs4LfXaaQW6uIpkjoiKn2g9B6nNQDraLyC3XgHP5cvX/qaqry43SwyqjbQtwRkScosDHl59r0DX1V/3xBtBYwdo8rAdX3I5h6z8lW12xGjOkmb20TuAiy8wSmzchdm52kWodUb7OkMk6CgRJRSDVbC97eNcfKk0wmpxnCJWhC+AiSzRVmgkpgp8NanuMcpI/X+W5qeqWO0w3DGzv43FkrYtfSkvpDdO4EvDL8bWX1Ad7mBoNVLWErcNf/uI+r/jFpKHgjvx3iqs2Q7vcfY706Py1m91vT0vs4SWXwzVV6pAVjD/kumL+nXfzfzAHw+A2vb6J2w06Rj71bqUkC2b8TpQIDAQAB'
]
}
],
name: 'Isaac\'s iPhone',
platform: 'IOS',
version: '8.1.3'
},
verify: function() { /* returns another transaction */ }
}, {
id: 'smsigwDlH85L9FyQK0g3',
provider: 'OKTA',
factorType: 'sms',
profile: {
phoneNumber: '+1 XXX-XXX-3355'
},
verify: function() { /* returns another transaction */ }
}, {
id: 'ostigevBq2NObXmTh0g3',
provider: 'OKTA',
factorType: 'token:software:totp',
profile: {
credentialId: 'isaac@example.org'
},
verify: function() { /* returns another transaction */ }
}, {
id: 'uftigiEmYTPOmvqTS0g3',
provider: 'GOOGLE',
factorType: 'token:software:totp',
profile: {
credentialId: 'isaac@example.org'
},
verify: function() { /* returns another transaction */ }
}],
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
factors: [{
id: 'ufsigasO4dVUPM5O40g3',
provider: 'OKTA',
factorType: 'question',
profile: {
question: 'disliked_food',
questionText: 'What is the food you least liked as a child?'
},
verify: function(options) { /* returns another transaction */ }
}, {
id: 'opfhw7v2OnxKpftO40g3',
provider: 'OKTA',
factorType: 'push',
profile: {
credentialId: 'isaac@example.org',
deviceType: 'SmartPhone_IPhone',
keys: [
{
kty: 'PKIX',
use: 'sig',
kid: 'default',
x5c: [
'MIIBIjANBgkqhkiG9w0BAQEFBAOCAQ8AMIIBCgKCAQEAs4LfXaaQW6uIpkjoiKn2g9B6nNQDraLyC3XgHP5cvX/qaqry43SwyqjbQtwRkScosDHl59r0DX1V/3xBtBYwdo8rAdX3I5h6z8lW12xGjOkmb20TuAiy8wSmzchdm52kWodUb7OkMk6CgRJRSDVbC97eNcfKk0wmpxnCJWhC+AiSzRVmgkpgp8NanuMcpI/X+W5qeqWO0w3DGzv43FkrYtfSkvpDdO4EvDL8bWX1Ad7mBoNVLWErcNf/uI+r/jFpKHgjvx3iqs2Q7vcfY706Py1m91vT0vs4SWXwzVV6pAVjD/kumL+nXfzfzAHw+A2vb6J2w06Rj71bqUkC2b8TpQIDAQAB'
]
}
],
name: 'Isaac\'s iPhone',
platform: 'IOS',
version: '8.1.3'
},
verify: function() { /* returns another transaction */ }
}, {
id: 'smsigwDlH85L9FyQK0g3',
provider: 'OKTA',
factorType: 'sms',
profile: {
phoneNumber: '+1 XXX-XXX-3355'
},
verify: function() { /* returns another transaction */ }
}, {
id: 'ostigevBq2NObXmTh0g3',
provider: 'OKTA',
factorType: 'token:software:totp',
profile: {
credentialId: 'isaac@example.org'
},
verify: function() { /* returns another transaction */ }
}, {
id: 'uftigiEmYTPOmvqTS0g3',
provider: 'GOOGLE',
factorType: 'token:software:totp',
profile: {
credentialId: 'isaac@example.org'
},
verify: function() { /* returns another transaction */ }
}],
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
#### [cancel()](#cancel)
</details>
#### [Verify Factor](http://developer.okta.com/docs/api/resources/authn.html#verify-factor)
##### [Verify Factor](https://developer.okta.com/docs/api/resources/authn#verify-factor)

@@ -1020,3 +1162,3 @@ To verify a factor, select one from the factors array, then use the following methods.

###### [OKTA question](http://developer.okta.com/docs/api/resources/authn.html#verify-security-question-factor)
###### [OKTA question](https://developer.okta.com/docs/api/resources/authn#verify-security-question-factor)

@@ -1033,5 +1175,5 @@ ```javascript

###### [OKTA push](https://developer.okta.com/docs/api/resources/authn.html#verify-push-factor)
###### [OKTA push](https://developer.okta.com/docs/api/resources/authn#verify-push-factor)
- `autoPush` - Optional parameter to send a push notification immediately the next time `verify` is called on a push factor
* `autoPush` - Optional parameter to send a push notification immediately the next time `verify` is called on a push factor

@@ -1048,3 +1190,3 @@ ```javascript

###### [All other factors](http://developer.okta.com/docs/api/resources/authn.html#verify-factor)
###### [All other factors](https://developer.okta.com/docs/api/resources/authn#verify-factor)

@@ -1059,42 +1201,46 @@ ```javascript

### MFA_CHALLENGE
#### MFA_CHALLENGE
The user must verify the factor-specific challenge.
<details>
<summary><b>Example Response</b></summary>
```javascript
{
status: 'MFA_CHALLENGE',
expiresAt: '2014-11-02T23:39:03.319Z',
factorResult: 'WAITING', // or CANCELLED, TIMEOUT, or ERROR
user: {
id: '00ugti3kwafWJBRIY0g3',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
```javascript
{
status: 'MFA_CHALLENGE',
expiresAt: '2014-11-02T23:39:03.319Z',
factorResult: 'WAITING', // or CANCELLED, TIMEOUT, or ERROR
user: {
id: '00ugti3kwafWJBRIY0g3',
profile: {
login: 'isaac@example.org',
firstName: 'Isaac',
lastName: 'Brock',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
},
},
},
factor: {
id: 'smsigwDlH85L9FyQK0g3',
factorType: 'sms',
provider: 'OKTA',
profile: {
phoneNumber: '+1 XXX-XXX-6688'
}
},
verify: function(options) { /* returns another transaction */ },
poll: function() { /* returns another transaction */ },
prev: function() { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
factor: {
id: 'smsigwDlH85L9FyQK0g3',
factorType: 'sms',
provider: 'OKTA',
profile: {
phoneNumber: '+1 XXX-XXX-6688'
}
},
verify: function(options) { /* returns another transaction */ },
poll: function() { /* returns another transaction */ },
prev: function() { /* returns another transaction */ },
cancel: function() { /* terminates the auth flow */ },
data: { /* the parsed json response */ }
}
```
#### [verify(options)](http://developer.okta.com/docs/api/resources/authn.html#verify-factor)
</details>
- `passCode` - OTP sent to device
- `autoPush` - Optional parameter to send a push notification immediately the next time `verify` is called on a push factor
##### `verify(options)`
* `passCode` - OTP sent to device
* `autoPush` - Optional parameter to send a push notification immediately the next time [`verify`](https://developer.okta.com/docs/api/resources/authn#verify-factor) is called on a push factor
```javascript

@@ -1107,7 +1253,7 @@ transaction.verify({

#### [poll(options)](http://developer.okta.com/docs/api/resources/authn.html#activate-push-factor)
##### `poll(options)`
- `autoPush` - Optional parameter to send a push notification immediately the next time `verify` is called on a push factor
* `autoPush` - Optional parameter to send a push notification immediately the next time `verify` is called on a push factor
Poll until factorResult is not WAITING. Throws AuthPollStopError if prev, resend, or cancel is called.
[Poll](https://developer.okta.com/docs/api/resources/authn#activate-push-factor) until factorResult is not WAITING. Throws AuthPollStopError if prev, resend, or cancel is called.

@@ -1120,5 +1266,5 @@ ```javascript

#### [prev()](http://developer.okta.com/docs/api/resources/authn.html#previous-transaction-state)
##### `prev()`
End current factor verification and return to `MFA_REQUIRED`.
End current factor verification and [return to](https://developer.okta.com/docs/api/resources/authn#previous-transaction-state) `MFA_REQUIRED`.

@@ -1129,32 +1275,37 @@ ```javascript

#### [cancel()](#cancel)
#### SUCCESS
### SUCCESS
The end of the authentication flow! This transaction contains a sessionToken you can exchange for an Okta cookie, an `id_token`, or `access_token`.
```javascript
{
expiresAt: '2015-06-08T23:34:34.000Z',
status: 'SUCCESS',
sessionToken: '00p8RhRDCh_8NxIin-wtF5M6ofFtRhfKWGBAbd2WmE',
user: {
id: '00uhm5QzwyZZxjrfp0g3',
profile: {
login: 'exampleUser@example.com',
firstName: 'Test',
lastName: 'User',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
<details>
<summary><b>Example Response</b></summary>
```javascript
{
expiresAt: '2015-06-08T23:34:34.000Z',
status: 'SUCCESS',
sessionToken: '00p8RhRDCh_8NxIin-wtF5M6ofFtRhfKWGBAbd2WmE',
user: {
id: '00uhm5QzwyZZxjrfp0g3',
profile: {
login: 'exampleUser@example.com',
firstName: 'Test',
lastName: 'User',
locale: 'en_US',
timeZone: 'America/Los_Angeles'
}
}
}
}
```
```
## session.setCookieAndRedirect(sessionToken, redirectUri)
</details>
### `session`
#### `session.setCookieAndRedirect(sessionToken, redirectUri)`
This allows you to create a session using a sessionToken.
- `sessionToken` - Ephemeral one-time token used to bootstrap an Okta session.
- `redirectUri` - After setting a cookie, Okta redirects to the specified URI. The default is the current URI.
* `sessionToken` - Ephemeral one-time token used to bootstrap an Okta session.
* `redirectUri` - After setting a cookie, Okta redirects to the specified URI. The default is the current URI.

@@ -1165,5 +1316,5 @@ ```javascript

## session.exists()
#### `session.exists()`
Returns a promise that resolves with `true` if there is an existing Okta [session](http://developer.okta.com/docs/api/resources/sessions.html#example), or `false` if not.
Returns a promise that resolves with `true` if there is an existing Okta [session](https://developer.okta.com/docs/api/resources/sessions#example), or `false` if not.

@@ -1181,5 +1332,5 @@ ```javascript

## session.get()
#### `session.get()`
Gets the active [session](http://developer.okta.com/docs/api/resources/sessions.html#example).
Gets the active [session](https://developer.okta.com/docs/api/resources/sessions#example).

@@ -1196,3 +1347,3 @@ ```javascript

## session.refresh()
#### `session.refresh()`

@@ -1211,7 +1362,48 @@ Refresh the current session by extending its lifetime. This can be used as a keep-alive operation.

## token.getWithoutPrompt(oauthOptions)
### `token`
#### Extended OpenID Connect options
The following configuration options can **only** be included in `token.getWithoutPrompt`, `token.getWithPopup`, or `token.getWithRedirect`.
| Options | Description |
| :-------: | ----------|
| `sessionToken` | Specify an Okta sessionToken to skip reauthentication when the user already authenticated using the Authentication Flow. |
| `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`. |
| | 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']` |
| `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). |
| `state` | Specify a state that will be validated in an OAuth response. This is usually only provided during redirect flows to obtain an authorization code. Defaults to a random string. |
| `nonce` | Specify a nonce that will be validated in an `id_token`. This is usually only provided during redirect flows to obtain an authorization code that will be exchanged for an `id_token`. Defaults to a random string. |
For a list of all available parameters that can be passed to the `/authorize` endpoint, see Okta's [Authorize Request API](https://developer.okta.com/docs/api/resources/oidc#request-parameters).
##### Example
```javascript
authClient.token.getWithoutPrompt({
sessionToken: '00p8RhRDCh_8NxIin-wtF5M6ofFtRhfKWGBAbd2WmE',
scopes: [
'openid',
'email',
'profile'
],
state: '8rFzn3MH5q',
nonce: '51GePTswrm',
// Use a custom IdP for social authentication
idp: '0oa62b57p7c8PaGpU0h7'
})
.then(function(tokenOrTokens) {
// manage token or tokens
})
.catch(function(err) {
// handle OAuthError
});
```
#### `token.getWithoutPrompt(oauthOptions)`
When you've obtained a sessionToken from the authorization flows, or a session already exists, you can obtain a token or tokens without prompting the user to log in.
- `oauthOptions` - See [OIDC Configuration](#openid-connect-options)
* `oauthOptions` - See [Extended OpenID Connect options](#extended-openid-connect-options)

@@ -1231,7 +1423,7 @@ ```javascript

## token.getWithPopup(oauthOptions)
#### `token.getWithPopup(oauthOptions)`
Create token with a popup.
- `oauthOptions` - See [OIDC Configuration](#openid-connect-options)
* `oauthOptions` - See [Extended OpenID Connect options](#extended-openid-connect-options)

@@ -1248,7 +1440,7 @@ ```javascript

## token.getWithRedirect(options)
#### `token.getWithRedirect(options)`
Create token using a redirect.
- `oauthOptions` - See [OIDC Configuration](#openid-connect-options)
* `oauthOptions` - See [Extended OpenID Connect options](#extended-openid-connect-options)

@@ -1259,3 +1451,3 @@ ```javascript

## token.parseFromUrl(options)
#### `token.parseFromUrl(options)`

@@ -1274,7 +1466,7 @@ Parses the access or ID Tokens from the url after a successful authentication redirect.

## token.decode(idTokenString)
#### `token.decode(idTokenString)`
Decode a raw ID Token
- `idTokenString` - an id_token JWT
* `idTokenString` - an id_token JWT

@@ -1285,11 +1477,11 @@ ```javascript

## token.refresh(tokenToRefresh)
#### `token.renew(tokenToRenew)`
Returns a new token if the Okta [session](http://developer.okta.com/docs/api/resources/sessions.html#example) is still valid.
Returns a new token if the Okta [session](https://developer.okta.com/docs/api/resources/sessions#example) is still valid.
- `tokenToRefresh` - an access token or ID token previously provided by Okta. note: this is not the raw JWT
* `tokenToRenew` - an access token or ID token previously provided by Okta. note: this is not the raw JWT
```javascript
// this token is provided by Okta via getWithoutPrompt, getWithPopup, and parseFromUrl
var tokenToRefresh = {
var tokenToRenew = {
idToken: 'YOUR_ID_TOKEN_JWT',

@@ -1299,8 +1491,8 @@ claims: { /* token claims */ },

scopes: ['openid', 'email'],
authorizeUrl: 'https://example.okta.com/oauth2/v1/authorize',
issuer: 'https://example.okta.com',
authorizeUrl: 'https://{yourOktaDomain}/oauth2/v1/authorize',
issuer: 'https://{yourOktaDomain}',
clientId: 'NPSfOkH5eZrTy8PMDlvx'
};
authClient.token.refresh(tokenToRefresh)
authClient.token.renew(tokenToRenew)
.then(function(freshToken) {

@@ -1314,7 +1506,7 @@ // manage freshToken

## token.getUserInfo(accessTokenObject)
#### `token.getUserInfo(accessTokenObject)`
Retrieve the [details about a user](http://developer.okta.com/docs/api/resources/oidc.html#response-example-success).
Retrieve the [details about a user](https://developer.okta.com/docs/api/resources/oidc#response-example-success).
- `accessTokenObject` - an access token returned by this library. note: this is not the raw access token
* `accessTokenObject` - an access token returned by this library. note: this is not the raw access token

@@ -1328,10 +1520,15 @@ ```javascript

## token.verify(idTokenObject)
#### `token.verify(idTokenObject)`
Verify the validity of an ID token's claims and check the signature on browsers that support web cryptography.
- `idTokenObject` - an ID token returned by this library. note: this is not the raw ID token JWT
* `idTokenObject` - an ID token returned by this library. note: this is not the raw ID token JWT
* `validationOptions` - Optional object to assert ID token claim values. Defaults to the configuration passed in during client instantiation.
```javascript
authClient.token.verify(idTokenObject)
var validationOptions = {
issuer: 'https://{yourOktaDomain}/oauth2/{authorizationServerId}'
}
authClient.token.verify(idTokenObject, validationOptions)
.then(function() {

@@ -1345,37 +1542,51 @@ // the idToken is valid

## tokenManager.add(key, token)
### `tokenManager`
After receiving an `access_token` or `id_token`, add it to the `tokenManager` to manage token expiration and refresh operations. When a token is added to the `tokenManager`, it is automatically refreshed when it expires.
#### `tokenManager.add(key, token)`
- `key` - Unique key to store the token in the `tokenManager`. This is used later when you want to get, delete, or refresh the token.
- `token` - Token object that will be added
After receiving an `access_token` or `id_token`, add it to the `tokenManager` to manage token expiration and renew operations. When a token is added to the `tokenManager`, it is automatically renewed when it expires.
* `key` - Unique key to store the token in the `tokenManager`. This is used later when you want to get, delete, or renew the token.
* `token` - Token object that will be added
```javascript
authClient.token.getWithPopup()
.then(function(idToken) {
authClient.tokenManager.add('my_id_token', idToken);
authClient.tokenManager.add('idToken', idToken);
});
```
## tokenManager.get(key)
#### `tokenManager.get(key)`
Get a token that you have previously added to the `tokenManager` with the given `key`.
Get a token that you have previously added to the `tokenManager` with the given `key`. The token object will be returned if it has not expired.
- `key` - Key for the token you want to get
* `key` - Key for the token you want to get
```javascript
var token = authClient.tokenManager.get('my_id_token');
authClient.tokenManager.get('idToken')
.then(function(token) {
if (token) {
// Token is valid
console.log(token);
} else {
// Token has expired
}
})
.catch(function(err) {
// OAuth Error
console.error(err);
});
```
## tokenManager.remove(key)
#### `tokenManager.remove(key)`
Remove a token from the `tokenManager` with the given `key`.
- `key` - Key for the token you want to remove
* `key` - Key for the token you want to remove
```javascript
authClient.tokenManager.remove('my_id_token');
authClient.tokenManager.remove('idToken');
```
## tokenManager.clear()
#### `tokenManager.clear()`

@@ -1388,32 +1599,33 @@ Remove all tokens from the `tokenManager`.

## tokenManager.refresh(key)
#### `tokenManager.renew(key)`
Manually refresh a token before it expires.
Manually renew a token before it expires.
- `key` - Key for the token you want to refresh
* `key` - Key for the token you want to renew
```javascript
// Because the refresh() method is async, you can wait for it to complete
// Because the renew() method is async, you can wait for it to complete
// by using the returned Promise:
authClient.tokenManager.refresh('my_id_token')
authClient.tokenManager.renew('idToken')
.then(function (newToken) {
// doSomethingWith(newToken);
console.log(newToken);
});
// Alternatively, you can subscribe to the 'refreshed' event:
authClient.tokenManager.on('refreshed', function (key, newToken, oldToken) {
// doSomethingWith(newToken);
// Alternatively, you can subscribe to the 'renewed' event:
authClient.tokenManager.on('renewed', function (key, newToken, oldToken) {
console.log(newToken);
});
authClient.tokenManager.refresh('my_id_token');
authClient.tokenManager.renew('idToken');
```
## tokenManager.on(event, callback[, context])
#### `tokenManager.on(event, callback[, context])`
Subscribe to an event published by the `tokenManager`.
- `event` - Event to subscribe to. Possible events are `expired`, `error`, and `refreshed`.
- `callback` - Function to call when the event is triggered
- `context` - Optional context to bind the callback to
* `event` - Event to subscribe to. Possible events are `expired`, `error`, and `renewed`.
* `callback` - Function to call when the event is triggered
* `context` - Optional context to bind the callback to
```javascript
// Triggered when the token has expired
authClient.tokenManager.on('expired', function (key, expiredToken) {

@@ -1424,208 +1636,61 @@ console.log('Token with key', key, ' has expired:');

authClient.tokenManager.on('error', function (err) {
console.log('TokenManager error:', err);
});
authClient.tokenManager.on('refreshed', function (key, newToken, oldToken) {
console.log('Token with key', key, 'has been refreshed');
authClient.tokenManager.on('renewed', function (key, newToken, oldToken) {
console.log('Token with key', key, 'has been renewed');
console.log('Old token:', oldToken);
console.log('New token:', newToken);
});
// Triggered when an OAuthError is returned via the API
authClient.tokenManager.on('error', function (err) {
console.log('TokenManager error:', err.message);
// err.name
// err.message
// err.errorCode
// err.errorSummary
});
```
## tokenManager.off(event[, callback])
#### `tokenManager.off(event[, callback])`
Unsubscribe from `tokenManager` events. If no callback is provided, unsubscribes all listeners from the event.
- `event` - Event to unsubscribe from
- `callback` - Optional callback that was used to subscribe to the event
* `event` - Event to unsubscribe from
* `callback` - Optional callback that was used to subscribe to the event
```javascript
authClient.tokenManager.off('refreshed');
authClient.tokenManager.off('refreshed', myRefreshedCallback);
authClient.tokenManager.off('renewed');
authClient.tokenManager.off('renewed', myRenewedCallback);
```
# Client Configuration
## Building the SDK
The only required configuration option is `url`. All others are optional.
In most cases, you won't need to build the SDK from source. If you want to build it yourself, you'll need to follow these steps:
```javascript
var config = {
url: 'https://your-org.okta.com',
clientId: 'your-client-id',
redirectUri: 'https://your.redirect.uri/redirect'
};
```bash
# Clone the repo
git clone https://github.com/okta/okta-auth-js.git
var authClient = new OktaAuth(config);
# Navigate into the new `okta-auth-js` filder, and install Okta node dependencies
cd okta-auth-js
npm install
# Build the SDK. The output will be under `dist`
npm run build
```
- **url:** The URL for your Okta organization
### Build and Test Commands
```javascript
// Production org with subdomain "acme"
url: 'https://acme.okta.com'
| Command | Description |
| --------------------- | ------------------------------ |
| `npm run build` | Build the SDK with a sourcemap |
| `npm test` | Run unit tests using PhantomJS |
| `npm run lint:report` | Run eslint linting tests |
// Can also target oktapreview and okta-emea, i.e.
url: 'https://acme.oktapreview.com'
```
## Contributing
- **ajaxRequest** The ajax request implementation. By default, this is implemented using [reqwest](https://github.com/ded/reqwest). To provide your own request library, implement the following interface:
We're happy to accept contributions and PRs! Please see the [contribution guide](contributing.md) to understand how to structure a contribution.
1. Must accept:
- method (http method)
- url (target url)
- args (object containing headers and data)
2. Must return a Promise that resolves with a raw XMLHttpRequest response
```javascript
ajaxRequest: function(method, url, args) {
/*
args is in the form:
{
headers: {
headerName: headerValue
},
data: postBodyData
}
*/
return Promise.resolve(/* a raw XMLHttpRequest response */);
}
```
If you're using a bundler like webpack or browserify, we have implementations for jquery and reqwest included. To use them, import the SDK like this:
```javascript
// reqwest
var OktaAuth = require('@okta/okta-auth-js/reqwest');
// jquery
var OktaAuth = require('@okta/okta-auth-js/jquery');
```
# OpenId Connect Options
Options for the [OpenId Connect](http://developer.okta.com/docs/api/resources/oidc.html) authentication flow. This flow is required for social authentication, and requires OAuth client registration with Okta. For instructions, see [Social Authentication](http://developer.okta.com/docs/api/resources/social_authentication.html).
## Can be in Client Configuration
These configuration options can be included when instantiating Okta Auth JS (`new OktaAuth(config)`) or in `token.getWithoutPrompt`, `token.getWithPopup`, or `token.getWithRedirect`. If included in both, the value passed in the method takes priority.
- **clientId:** Client Id pre-registered with Okta for the OIDC authentication flow.
```javascript
clientId: 'GHtf9iJdr60A9IYrR0jw'
```
- **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.
```javascript
redirectUri: 'https://acme.com/oauth2/callback/home'
```
- **issuer:** Specify a custom issuer to perform the OIDC flow. Defaults to the baseUrl.
```javascript
issuer: 'https://your-org.okta.com/oauth2/aus8aus76q8iphupD0h7'
```
- **authorizeUrl:** Specify a custom authorizeUrl to perform the OIDC flow. Defaults to the issuer plus "/v1/authorize".
```javascript
issuer: 'https://your-org.okta.com/oauth2/aus8aus76q8iphupD0h7',
authorizeUrl: 'https://your-org.okta.com/oauth2/aus8aus76q8iphupD0h7/v1/authorize'
```
- **userinfoUrl:** Specify a custom userinfoUrl. Defaults to the issuer plus "/v1/userinfo".
```javascript
issuer: 'https://your-org.okta.com/oauth2/aus8aus76q8iphupD0h7',
userinfoUrl: 'https://your-org.okta.com/oauth2/aus8aus76q8iphupD0h7/v1/userinfo'
```
## Cannot be in Client Configuration
- **sessionToken** Specify an Okta sessionToken to skip reauthentication when the user already authenticated using the Authentication Flow.
```javascript
sessionToken: '00p8RhRDCh_8NxIin-wtF5M6ofFtRhfKWGBAbd2WmE'
```
- **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`.
- `okta_post_message` - Used with `token.getWithPopup` and `token.getWithoutPrompt`. Uses [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) to send the response from the popup or iframe to the origin window.
- `fragment` - Default value when using `token.getWithRedirect` and `responseType != 'code'`. Returns the authorization response in the hash fragment of the URL after the authorization redirect.
- `query` - Default value when using `token.getWithRedirect` and `responseType = 'code'`. Returns the authorization response in the query string of the URL after the authorization redirect.
- `form_post` - Returns the authorization response as a form POST after the authorization redirect. Use this when using `token.getWithRedirect` and you do not want the response returned in the URL.
```javascript
// Use form_post instead of query in the Authorization Code flow
responseType: 'code',
responseMode: 'form_post'
```
- **responseType:** Specify the response type for OIDC authentication. Defaults to `id_token`.
Valid response types are `id_token`, `access_token`, and `code`. Note that `code` goes through the Authorization Code flow, which requires the server to exchange the Authorization Code for tokens.
```javascript
// Specifying a single responseType
responseType: 'token'
// 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']
```
- **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']`.
Valid OIDC scopes: `openid`, `email`, `profile`, `address`, `phone`, `groups`, `offline_access`
```javascript
scopes: ['openid', 'email', 'profile', 'address', 'phone', 'groups', 'offline_access']
```
- **state:** Specify a state that will be validated in an OAuth response. This is usually only provided during redirect flows to obtain an authorization code. Defaults to a random string.
```javascript
state: '8rFzn3MH5q'
```
- **nonce:** Specify a nonce that will be validated in an `id_token`. This is usually only provided during redirect flows to obtain an authorization code that will be exchanged for an `id_token`. Defaults to a random string.
```javascript
nonce: '51GePTswrm'
```
# Developing the Okta Auth Client
## Building the Client
1. Clone the repo.
```bash
[path]$ git clone git@github.com:okta/okta-auth-js.git
```
2. Navigate to the new `okta-auth-js` folder, and install the Okta node dependencies.
```bash
[path/okta-auth-js]$ npm install
```
3. Build the SDK. The output will be under `dist/browser/`. The standalone version is `okta-auth-js.min.js`.
```bash
[path/okta-auth-js]$ npm run build
```
## Build and Test Commands
| Command | Description |
| --- | --- |
| `npm run build` | Build the SDK with a sourcemap |
| `npm test` | Run unit tests using PhantomJS |
| `npm run lint:report` | Run eslint linting tests |
[devforum]: https://devforum.okta.com/
[lang-landing]: https://developer.okta.com/code/javascript
[github-issues]: https://github.com/okta/okta-auth-js/issues
[github-releases]: https://github.com/okta/okta-auth-js/releases

@@ -0,2 +1,15 @@

/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
var reqwestRequest = require('./reqwestRequest');
module.exports = require('../lib/clientBuilder')(reqwestRequest);
/*!
* Copyright (c) 2015-2016, Okta, Inc. and/or its affiliates. All rights reserved.
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")

@@ -4,0 +4,0 @@ *

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

Sorry, the diff of this file is not supported yet

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