@okta/okta-auth-js
Advanced tools
Comparing version 2.6.0 to 2.6.1
# Changelog | ||
## 2.6.1 | ||
### Features | ||
- [d8d2fee](https://github.com/okta/okta-auth-js/commit/d8d2feee6832fde7c297fd63f58e738c478d338b) TokenManager: new option `expireEarlySeconds` | ||
### Bug Fixes | ||
- TokenManager: Re-enables use of custom storage keys | ||
### Other | ||
- TokenManager: Document the `maxClockSkew` option | ||
## 2.6.0 | ||
### Features | ||
- [0a8a4e1](https://github.com/okta/okta-auth-js/commit/0a8a4e16d75028900280ab93e561d9e4368a484f) PKCE support | ||
### Bug Fixes | ||
- TokenManager: tokens were being expired 5 minutes early | ||
## 2.5.0 | ||
@@ -4,0 +23,0 @@ |
@@ -13,3 +13,3 @@ module.exports = { | ||
"PKCE_STORAGE_NAME": "okta-pkce-storage", | ||
"SDK_VERSION": "2.6.0" | ||
"SDK_VERSION": "2.6.1" | ||
}; |
@@ -138,3 +138,3 @@ /*! | ||
var now = Math.floor(new Date().getTime()/1000); | ||
var now = Math.floor(Date.now()/1000); | ||
@@ -141,0 +141,0 @@ if (claims.iss !== iss) { |
@@ -22,3 +22,20 @@ /*! | ||
var storageBuilder = require('./storageBuilder'); | ||
var SdkClock = require('./clock'); | ||
var DEFAULT_OPTIONS = { | ||
autoRenew: true, | ||
storage: 'localStorage', | ||
expireEarlySeconds: 30 | ||
}; | ||
function getExpireTime(tokenMgmtRef, token) { | ||
var expireTime = token.expiresAt - tokenMgmtRef.options.expireEarlySeconds; | ||
return expireTime; | ||
} | ||
function hasExpired(tokenMgmtRef, token) { | ||
var expireTime = getExpireTime(tokenMgmtRef, token); | ||
return expireTime <= tokenMgmtRef.clock.now(); | ||
} | ||
function emitExpired(tokenMgmtRef, key, token) { | ||
@@ -51,4 +68,4 @@ tokenMgmtRef.emitter.emit('expired', key, token); | ||
function setExpireEventTimeout(sdk, tokenMgmtRef, key, token) { | ||
var clockSkew = sdk.options.maxClockSkew * 1000; | ||
var expireEventWait = (token.expiresAt * 1000) - (Date.now() - clockSkew); | ||
var expireTime = getExpireTime(tokenMgmtRef, token); | ||
var expireEventWait = Math.max(expireTime - tokenMgmtRef.clock.now(), 0) * 1000; | ||
@@ -106,8 +123,7 @@ // Clear any existing timeout | ||
var token = get(storage, key); | ||
var clockSkew = sdk.options.maxClockSkew * 1000; | ||
if (!token || (token.expiresAt * 1000 - clockSkew) > Date.now()) { | ||
if (!token || !hasExpired(tokenMgmtRef, token)) { | ||
return resolve(token); | ||
} | ||
var tokenPromise = tokenMgmtRef.autoRenew | ||
var tokenPromise = tokenMgmtRef.options.autoRenew | ||
? renew(sdk, tokenMgmtRef, storage, key) | ||
@@ -147,25 +163,23 @@ : remove(tokenMgmtRef, storage, key); | ||
.then(function(freshTokens) { | ||
// We may receive more tokens than we requested | ||
var map = {}; | ||
if (freshTokens instanceof Array === false) { | ||
freshTokens = [freshTokens]; | ||
var freshToken = freshTokens; | ||
// With PKCE flow we will receive multiple tokens. Find the one we are looking for | ||
if (freshTokens instanceof Array) { | ||
freshToken = freshTokens.find(function(freshToken) { | ||
return (freshToken.idToken && token.idToken) || (freshToken.accessToken && token.accessToken); | ||
}); | ||
} | ||
freshTokens.forEach(function(freshToken) { | ||
var inferredKey = freshToken.idToken ? 'idToken' : freshToken.accessToken ? 'accessToken' : key; | ||
map[inferredKey] = freshToken; | ||
var oldToken = get(storage, inferredKey); | ||
if (!oldToken) { | ||
// It is possible to enter a state where the tokens have been cleared | ||
// after a renewal request was triggered. To ensure we do not store a | ||
// renewed token, we verify the promise key doesn't exist and return. | ||
return; | ||
} | ||
add(sdk, tokenMgmtRef, storage, inferredKey, freshToken); | ||
tokenMgmtRef.emitter.emit('renewed', inferredKey, freshToken, oldToken); | ||
}); | ||
var oldToken = get(storage, key); | ||
if (!oldToken) { | ||
// It is possible to enter a state where the tokens have been cleared | ||
// after a renewal request was triggered. To ensure we do not store a | ||
// renewed token, we verify the promise key doesn't exist and return. | ||
return; | ||
} | ||
add(sdk, tokenMgmtRef, storage, key, freshToken); | ||
tokenMgmtRef.emitter.emit('renewed', key, freshToken, oldToken); | ||
// Remove existing promise key | ||
delete tokenMgmtRef.renewPromise[key]; | ||
return map[key]; // return the specific token requested | ||
return freshToken; | ||
}) | ||
@@ -190,7 +204,3 @@ .fail(function(err) { | ||
function TokenManager(sdk, options) { | ||
options = options || {}; | ||
options.storage = options.storage || 'localStorage'; | ||
if (!options.autoRenew && options.autoRenew !== false) { | ||
options.autoRenew = true; | ||
} | ||
options = util.extend({}, DEFAULT_OPTIONS, util.removeNils(options)); | ||
@@ -222,5 +232,7 @@ if (options.storage === 'localStorage' && !storageUtil.browserHasLocalStorage()) { | ||
var clock = SdkClock.create(sdk, options); | ||
var tokenMgmtRef = { | ||
clock: clock, | ||
options: options, | ||
emitter: new Emitter(), | ||
autoRenew: options.autoRenew, | ||
expireTimeouts: {}, | ||
@@ -227,0 +239,0 @@ renewPromise: {} |
@@ -130,7 +130,10 @@ /*! | ||
util.extend = function() { | ||
// First object will be modified! | ||
var obj1 = arguments[0]; | ||
// Properties from other objects will be copied over | ||
var objArray = [].slice.call(arguments, 1); | ||
objArray.forEach(function(obj) { | ||
for (var prop in obj) { | ||
if (obj.hasOwnProperty(prop)) { | ||
// copy over all properties with defined values | ||
if (obj.hasOwnProperty(prop) && obj[prop] !== undefined) { | ||
obj1[prop] = obj[prop]; | ||
@@ -140,2 +143,3 @@ } | ||
}); | ||
return obj1; // return the modified object | ||
}; | ||
@@ -142,0 +146,0 @@ |
{ | ||
"name": "@okta/okta-auth-js", | ||
"description": "The Okta Auth SDK", | ||
"version": "2.6.0", | ||
"version": "2.6.1", | ||
"homepage": "https://github.com/okta/okta-auth-js", | ||
@@ -83,5 +83,5 @@ "license": "Apache-2.0", | ||
"okta": { | ||
"commitSha": "f5f930605fda763c22ef2bf5c03ba4d83ad4ad56", | ||
"fullVersion": "2.6.0-20190603213603-f5f9306" | ||
"commitSha": "ea3f395ba375990bed79421561369904bd4b1333", | ||
"fullVersion": "2.6.1-20190723001632-ea3f395" | ||
} | ||
} |
@@ -149,3 +149,2 @@ [<img src="https://devforum.okta.com/uploads/oktadev/original/1X/bf54a16b5fda189e4ad2706fb57cbb7a1e5b8deb.png" align="right" width="256px"/>](https://devforum.okta.com/) | ||
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. | ||
@@ -159,2 +158,12 @@ | ||
Renewing tokens slightly early helps ensure a stable user experience. By default, the `expired` event will fire 30 seconds before actual expiration time. If `autoRenew` is set to true, tokens will be renewed within 30 seconds of expiration, if accessed with `tokenManager.get()`. You can customize this value by setting the `expireEarlySeconds` option. The value should be large enough to account for network latency between the client and Okta's servers. | ||
```javascript | ||
// Emit expired event 2 minutes before expiration | ||
// Tokens accessed with tokenManager.get() will auto-renew within 2 minutes of expiration | ||
tokenManager: { | ||
expireEarlySeconds: 120 | ||
} | ||
``` | ||
#### Additional Options | ||
@@ -173,2 +182,3 @@ | ||
| | This option should be used only for browser support and testing purposes. | | ||
| `maxClockSkew` | Defaults to 300 (five minutes). This is the maximum difference allowed between a client's clock and Okta's, in seconds, when validating tokens. Setting this to 0 is not recommended, because it increases the likelihood that valid tokens will fail validation. | ||
@@ -175,0 +185,0 @@ ##### Example Client |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
1286692
45
3472
1778