Skip to content

Commit

Permalink
feat: #251 support retry for silent renew
Browse files Browse the repository at this point in the history
  • Loading branch information
pamapa committed Jan 13, 2022
1 parent a360d71 commit 1f4e6a3
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 4 deletions.
7 changes: 5 additions & 2 deletions docs/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ removed.
- type of `popupWindowFeatures` changed from a string to a dictionary
- additionally, its default dimensions are now responsive to the opener
window's
- a new property `revokeTokenTypes: ('access_token' | 'refresh_token')[]` was
added
- a new property `revokeTokenTypes: ('access_token' | 'refresh_token')[]` was added
- by default, `UserManager` will attempt revoking both token types when
`revokeTokensOnSignout` is `true`. Compared to 1.x, sign out will now fail
if revocations fail.
- a new property `retrySilentRenew: boolean` was added
- by default `SilentRenewService` will retry every 5s until it receives a response
from the authority server. If you depend on your own custom silent renew error
event handler you can set `false`.

### [UserManager](https://authts.github.io/oidc-client-ts/classes/UserManager.html)

Expand Down
3 changes: 3 additions & 0 deletions docs/oidc-client-ts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@ export interface UserManagerSettings extends OidcClientSettings {
// (undocumented)
query_status_response_type?: string;
redirectMethod?: "replace" | "assign";
retrySilentRenew?: boolean;
revokeTokensOnSignout?: boolean;
revokeTokenTypes?: ("access_token" | "refresh_token")[];
silent_redirect_uri?: string;
Expand Down Expand Up @@ -998,6 +999,8 @@ export class UserManagerSettingsStore extends OidcClientSettingsStore {
// (undocumented)
readonly redirectMethod: "replace" | "assign";
// (undocumented)
readonly retrySilentRenew: boolean;
// (undocumented)
readonly revokeTokensOnSignout: boolean;
// (undocumented)
readonly revokeTokenTypes: ("access_token" | "refresh_token")[];
Expand Down
17 changes: 15 additions & 2 deletions src/SilentRenewService.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

import { Logger } from "./utils";
import { Logger, Timer } from "./utils";
import type { UserManager } from "./UserManager";
import type { AccessTokenCallback } from "./AccessTokenEvents";
import { ErrorResponse } from "./ErrorResponse";

/**
* @internal
*/
export class SilentRenewService {
protected _logger = new Logger("SilentRenewService");
private _isStarted = false;
private readonly _retryTimer = new Timer("Retry Silent Renew");

public constructor(private _userManager: UserManager) {}

Expand All @@ -19,6 +21,7 @@ export class SilentRenewService {
if (!this._isStarted) {
this._isStarted = true;
this._userManager.events.addAccessTokenExpiring(this._tokenExpiring);
this._retryTimer.addHandler(this._tokenExpiring);

// this will trigger loading of the user so the expiring events can be initialized
try {
Expand All @@ -34,6 +37,8 @@ export class SilentRenewService {

public stop(): void {
if (this._isStarted) {
this._retryTimer.cancel();
this._retryTimer.removeHandler(this._tokenExpiring);
this._userManager.events.removeAccessTokenExpiring(this._tokenExpiring);
this._isStarted = false;
}
Expand All @@ -44,7 +49,15 @@ export class SilentRenewService {
try {
await this._userManager.signinSilent();
logger.debug("silent token renewal successful");
} catch (err) {
}
catch (err) {
if (this._userManager.settings.retrySilentRenew && !(err instanceof ErrorResponse)) {
// no response from authority server, e.g. IFrame timeout, ...
logger.warn("Error from signinSilent:", err, "retry in 5s");
this._retryTimer.init(5);
return;
}

logger.error("Error from signinSilent:", err);
this._userManager.events._raiseSilentRenewError(err as Error);
}
Expand Down
5 changes: 5 additions & 0 deletions src/UserManagerSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export interface UserManagerSettings extends OidcClientSettings {
validateSubOnSilentRenew?: boolean;
/** Flag to control if id_token is included as id_token_hint in silent renew calls (default: false) */
includeIdTokenInSilentRenew?: boolean;
/** Retry silent renew every 5s until we receive a response from the authority server (default: true) */
retrySilentRenew?: boolean;

/** Will raise events for when user has performed a signout at the OP (default: false) */
monitorSession?: boolean;
Expand Down Expand Up @@ -84,6 +86,7 @@ export class UserManagerSettingsStore extends OidcClientSettingsStore {
public readonly automaticSilentRenew: boolean;
public readonly validateSubOnSilentRenew: boolean;
public readonly includeIdTokenInSilentRenew: boolean;
public readonly retrySilentRenew: boolean;

public readonly monitorSession: boolean;
public readonly monitorAnonymousSession: boolean;
Expand All @@ -110,6 +113,7 @@ export class UserManagerSettingsStore extends OidcClientSettingsStore {
automaticSilentRenew = true,
validateSubOnSilentRenew = true,
includeIdTokenInSilentRenew = false,
retrySilentRenew = true,

monitorSession = false,
monitorAnonymousSession = false,
Expand Down Expand Up @@ -137,6 +141,7 @@ export class UserManagerSettingsStore extends OidcClientSettingsStore {
this.automaticSilentRenew = automaticSilentRenew;
this.validateSubOnSilentRenew = validateSubOnSilentRenew;
this.includeIdTokenInSilentRenew = includeIdTokenInSilentRenew;
this.retrySilentRenew = retrySilentRenew;

this.monitorSession = monitorSession;
this.monitorAnonymousSession = monitorAnonymousSession;
Expand Down

0 comments on commit 1f4e6a3

Please sign in to comment.