Skip to content

Commit

Permalink
Merge pull request #148 from DonOmalVindula/v0.4.12-pre-release
Browse files Browse the repository at this point in the history
Add logic to gracefully retry 401 error
  • Loading branch information
DonOmalVindula authored Mar 10, 2023
2 parents bd666c5 + cdf5c88 commit 22da096
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
33 changes: 32 additions & 1 deletion lib/src/helpers/authentication-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
TokenResponse
} from "@asgardeo/auth-js";
import { SPAHelper } from "./spa-helper";
import { Message, SPAUtils, SessionManagementHelperInterface } from "..";
import { HttpRequestInterface, Message, SPAUtils, SessionManagementHelperInterface } from "..";
import {
ACCESS_TOKEN_INVALID,
CHECK_SESSION_SIGNED_IN,
Expand Down Expand Up @@ -61,6 +61,7 @@ export class AuthenticationHelper<
protected _authenticationClient: AsgardeoAuthClient<T>;
protected _dataLayer: DataLayer<T>;
protected _spaHelper: SPAHelper<T>;
protected _isTokenRefreshing: boolean;

public constructor(
authClient: AsgardeoAuthClient<T>,
Expand All @@ -69,6 +70,7 @@ export class AuthenticationHelper<
this._authenticationClient = authClient;
this._dataLayer = this._authenticationClient.getDataLayer();
this._spaHelper = spaHelper;
this._isTokenRefreshing = false;
}

public enableHttpHandler(httpClient: HttpClientInstance): void {
Expand Down Expand Up @@ -189,6 +191,22 @@ export class AuthenticationHelper<
}
}

protected async retryFailedRequests (failedRequest: HttpRequestInterface): Promise<HttpResponse> {
if (this._isTokenRefreshing) {
return new Promise(() => setTimeout(() => {
return this.retryFailedRequests(failedRequest);
}, 500));
} else {
return this.httpRequest(failedRequest.httpClient,
failedRequest.requestConfig,
failedRequest.isHttpHandlerEnabled,
failedRequest.httpErrorCallback,
failedRequest.httpFinishCallback,
failedRequest.enableRetrievingSignOutURLFromSession
);
}
}

public async httpRequest(
httpClient: HttpClientInstance,
requestConfig: HttpRequestConfig,
Expand Down Expand Up @@ -219,13 +237,26 @@ export class AuthenticationHelper<
})
.catch(async (error: HttpError) => {
if (error?.response?.status === 401 || !error?.response) {
if (this._isTokenRefreshing) {
return this.retryFailedRequests({
enableRetrievingSignOutURLFromSession,
httpClient,
httpErrorCallback,
httpFinishCallback,
isHttpHandlerEnabled,
requestConfig
});
}
this._isTokenRefreshing = true;
// Try to refresh the token
let refreshAccessTokenResponse: BasicUserInfo;
try {
refreshAccessTokenResponse = await this.refreshAccessToken(
enableRetrievingSignOutURLFromSession
);
this._isTokenRefreshing = false;
} catch (refreshError: any) {
this._isTokenRefreshing = false;
if (isHttpHandlerEnabled) {
if (typeof httpErrorCallback === "function") {
await httpErrorCallback({
Expand Down
12 changes: 11 additions & 1 deletion lib/src/models/http-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
*/

import { AxiosRequestConfig } from "axios";
import { HttpError, HttpResponse } from ".";
import { HttpClientInstance, HttpError, HttpResponse } from ".";
import { SPACustomGrantConfig } from "..";

export interface HttpClient {
requestStartCallback: () => void;
Expand All @@ -33,6 +34,15 @@ export interface HttpRequestConfig extends AxiosRequestConfig {
startTimeInMs?: number
}

export interface HttpRequestInterface {
httpClient: HttpClientInstance,
requestConfig: HttpRequestConfig,
isHttpHandlerEnabled?: boolean,
httpErrorCallback?: (error: HttpError) => void | Promise<void>,
httpFinishCallback?: () => void,
enableRetrievingSignOutURLFromSession?: (config: SPACustomGrantConfig) => void
}

export {
AxiosResponse as HttpResponse,
Method as HttpMethod,
Expand Down

0 comments on commit 22da096

Please sign in to comment.