Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getOrRenewAccessToken #1507

Merged
merged 3 commits into from
Apr 18, 2024
Merged

getOrRenewAccessToken #1507

merged 3 commits into from
Apr 18, 2024

Conversation

jaredperreault-okta
Copy link
Contributor

No description provided.

Copy link
Contributor

@glenfannin-okta glenfannin-okta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few verbiage nits, but LGTM!

One question for my own understanding, how does the app know the difference between when no token exists (unauthenticated) vs when the access token is just not in storage?

@@ -0,0 +1,28 @@
# Future of AuthJS `autoRenew`

We have been tracking browsers the changes browsers has been making to long running timers, especially in inactive tabs, and have begun to receive reports of flaky and unpredictable behavior from our [Active AutoRenew](../README.md#autorenew-1). We have spiked on the usage of Web Worker based timers, however we decided not to move forward with that approach. Active AutoRenew served it's purpose, however the introduction of [refresh tokens](https://developer.okta.com/docs/guides/refresh-tokens/main/#about-refresh-tokens) have made it a bit antiquated. A better, more reliable approach to token renewal is renewing the token (if needed) when tokens are read from storage. The [isAuthenticated()](../README.md#isauthenticatedoptions) method already does this and we have added a new method [getOrRenewAccessToken()](../README.md#getorrenewaccesstoken) for convenience. Unfortunately we cannot make this the default behavior when tokens are read because storage operations are not `async` and performing a token renewal is (results in http request).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We have been tracking browsers the changes browsers has been making to long running timers, especially in inactive tabs, and have begun to receive reports of flaky and unpredictable behavior from our [Active AutoRenew](../README.md#autorenew-1). We have spiked on the usage of Web Worker based timers, however we decided not to move forward with that approach. Active AutoRenew served it's purpose, however the introduction of [refresh tokens](https://developer.okta.com/docs/guides/refresh-tokens/main/#about-refresh-tokens) have made it a bit antiquated. A better, more reliable approach to token renewal is renewing the token (if needed) when tokens are read from storage. The [isAuthenticated()](../README.md#isauthenticatedoptions) method already does this and we have added a new method [getOrRenewAccessToken()](../README.md#getorrenewaccesstoken) for convenience. Unfortunately we cannot make this the default behavior when tokens are read because storage operations are not `async` and performing a token renewal is (results in http request).
We have been tracking the changes browsers have been making to long running timers, especially in inactive tabs, and have begun to receive reports of flaky and unpredictable behavior from our [Active AutoRenew](../README.md#autorenew-1). We have spiked on the usage of Web Worker based timers, however we decided not to move forward with that approach. Active AutoRenew served it's purpose, however the introduction of [refresh tokens](https://developer.okta.com/docs/guides/refresh-tokens/main/#about-refresh-tokens) have made it a bit antiquated. A better, more reliable approach to token renewal is renewing the token (if needed) when tokens are read from storage. The [isAuthenticated()](../README.md#isauthenticatedoptions) method already does this and we have added a new method [getOrRenewAccessToken()](../README.md#getorrenewaccesstoken) for convenience. Unfortunately we cannot make this the default behavior when tokens are read because storage operations are not `async` and performing a token renewal results in http request.

@@ -439,6 +445,14 @@ export class TokenManager implements TokenManagerInterface {
.then(tokens => {
this.setTokens(tokens);

// return accessToken in case where access token doesn't exist
// but refresh token does exists
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// but refresh token does exists
// but refresh token exists

expect(renewSpy).toHaveBeenCalled();
});

it('returns renewed access token when no stored access token exists', async () => {
Copy link
Contributor

@glenfannin-okta glenfannin-okta Apr 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: possibly consider including in the test name that only refresh token exists

Suggested change
it('returns renewed access token when no stored access token exists', async () => {
it('returns renewed access token when only stored refresh token exists', async () => {

README.md Outdated
### `getOrRenewAccessToken()`

Reads the `accessToken` from storage and will attempt a token renewal if expired.
Returns the access token string or `null` if the doesn't exist or a renewal cannot be completed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Returns the access token string or `null` if the doesn't exist or a renewal cannot be completed
Returns the access token string if it exists. Returns `null` if the access token doesn't exist or a renewal cannot be completed

}
try {
const key = this.tokenManager.getStorageKeyByType('accessToken');
const token = await this.tokenManager.renew(key ?? 'accessToken') as AccessToken;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.renew() returns Promise<Token | undefined>. Shouldn't you check truthiness instead of using type coercion?

README.md Outdated
## Release Status

:heavy_check_mark: The current stable major version series is: `7.x`

| Version | Status |
| ------- | -------------------------------- |
| `7.x` | :heavy_check_mark: Stable |
| `6.x` | :warning: Retiring on 2023-09-30 |
| `6.x` | :x: Retired |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
| `6.x` | :x: Retired |
| `6.x` | :x: Retired |

README.md Outdated
@@ -36,14 +36,19 @@ You can learn more on the [Okta + JavaScript][lang-landing] page in our document

This library uses semantic versioning and follows Okta's [library version policy](https://developer.okta.com/code/library-versions/).

> :warning: :warning: :warning: :warning: :warning:<br>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tip: in markdown, two spaces at EOL will be a newline

auth.tokenManager.clear();
});

const now = Math.floor(Date.now() / 1000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: move now into tests or beforeEach for better isolation?

@@ -355,6 +355,32 @@ describe('TokenManager', function() {
});
return p1;
});

it('performs renew when no access token exists but refresh token is present', async () => {
expect.assertions(4);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never knew this, TIL

shuowu-okta
shuowu-okta previously approved these changes Apr 12, 2024
Copy link
Contributor

@lesterchoi-okta lesterchoi-okta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can re-approve if taking out of draft mode requires

@oktapp-aperture-okta oktapp-aperture-okta bot merged commit 4269d34 into master Apr 18, 2024
1 check passed
@oktapp-aperture-okta oktapp-aperture-okta bot deleted the jp-OKTA-718696 branch April 18, 2024 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants