From 7efbab245d341a00687bf1bda1a821ed0df1276a Mon Sep 17 00:00:00 2001 From: Aman Kumar Date: Fri, 7 Mar 2025 16:56:15 +0530 Subject: [PATCH] feat: retry the requests that were pending due to token expiration --- lib/core/concurrency-queue.js | 13 ++++--- lib/core/oauthHandler.js | 3 ++ types/oauthHandler.d.ts | 64 ++++++++++++++++++++++++++++++++--- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/lib/core/concurrency-queue.js b/lib/core/concurrency-queue.js index d977bb26..e3286913 100644 --- a/lib/core/concurrency-queue.js +++ b/lib/core/concurrency-queue.js @@ -130,18 +130,23 @@ export function ConcurrencyQueue ({ axios, config }) { //Refresh Access Token const refreshAccessToken = async () => { try { + // Try to refresh the token await new OAuthHandler(axios).refreshAccessToken(); this.paused = false; // Resume the request queue once the token is refreshed + + // Retry the requests that were pending due to token expiration this.running.forEach(({ request, resolve, reject }) => { - resolve(request); // Retry the queued requests + // Retry the request + axios(request).then(resolve).catch(reject); }); - this.running = []; // Clear the running queue + this.running = []; // Clear the running queue after retrying requests } catch (error) { - this.paused = false; // Ensure we stop queueing requests on failure + this.paused = false; // stop queueing requests on failure this.running.forEach(({ reject }) => reject(error)); // Reject all queued requests this.running = []; // Clear the running queue } - }; + } + const delay = (time, isRefreshToken = false) => { if (!this.paused) { diff --git a/lib/core/oauthHandler.js b/lib/core/oauthHandler.js index 699abdc8..69a0873c 100644 --- a/lib/core/oauthHandler.js +++ b/lib/core/oauthHandler.js @@ -89,6 +89,9 @@ export default class OAuthHandler { */ async authorize() { try { + if (!this.OAuthBaseURL) { + throw new Error('OAuthBaseURL is not set'); + } const baseUrl = `${this.OAuthBaseURL}/#!/apps/${this.appId}/authorize`; const authUrl = new URL(baseUrl); authUrl.searchParams.set('response_type', 'code'); // Using set() to avoid duplicate parameters diff --git a/types/oauthHandler.d.ts b/types/oauthHandler.d.ts index 7d319347..0a16bf29 100644 --- a/types/oauthHandler.d.ts +++ b/types/oauthHandler.d.ts @@ -5,11 +5,11 @@ interface OAuthResponse { expires_in: number; organization_uid: string; user_uid: string; - token_type: string, - location: string, - region: string, - authorization_type: string, - stack_api_key: string + token_type: string; + location: string; + region: string; + authorization_type: string; + stack_api_key: string; } export default class OAuthHandler { @@ -45,6 +45,60 @@ export default class OAuthHandler { */ getAccessToken(): string; + /** + * Get the current refresh token + * @returns The refresh token + */ + getRefreshToken(): string; + + /** + * Get the current organization UID + * @returns The organization UID + */ + getOrganizationUID(): string; + + /** + * Get the current user UID + * @returns The user UID + */ + getUserUID(): string; + + /** + * Get the token expiry time + * @returns The token expiry time + */ + getTokenExpiryTime(): string; + + /** + * Set the access token + * @param token - The access token + */ + setAccessToken(token: string): void; + + /** + * Set the refresh token + * @param token - The refresh token + */ + setRefreshToken(token: string): void; + + /** + * Set organization UID + * @param organizationUID - The organization UID + */ + setOrganizationUID(organizationUID: string): void; + + /** + * Set user UID + * @param userUID - The user UID + */ + setUserUID(userUID: string): void; + + /** + * Set expiry time + * @param expiryTime - The expiry time + */ + setTokenExpiryTime(expiryTime: Date): void; + /** * Handle the OAuth redirect URL and exchange the authorization code for a token * @param url - The redirect URL containing the authorization code