diff --git a/wp-content/themes/moonshine/server/utils/auth.ts b/wp-content/themes/moonshine/server/utils/auth.ts index a6aef8e..48bb884 100644 --- a/wp-content/themes/moonshine/server/utils/auth.ts +++ b/wp-content/themes/moonshine/server/utils/auth.ts @@ -40,15 +40,36 @@ function getAuthUser(user: AuthUserFragment): User { }; } +// Track in-flight refreshAuthToken calls to prevent duplicate requests +const refreshTokenPromises = new Map>(); + // Refresh auth token by calling remote GraphQL endpoint directly export async function refreshAuthToken(refreshToken: string): Promise { - const { public: { wpUrl } } = useRuntimeConfig(); - const endpoint = `${wpUrl}/graphql`; - const { data } = await executeGraphQLHTTP>({ - query: AuthRefreshTokenDocument, - variables: { refreshToken }, - }, { endpoint }); - return data?.refreshToken?.authToken || undefined; + // Return existing in-flight promise if available + const inFlight = refreshTokenPromises.get(refreshToken); + if (inFlight) { + return inFlight; + } + + const refreshPromise = (async () => { + console.log(`Refreshing auth token: ${refreshToken}`); + const { public: { wpUrl } } = useRuntimeConfig(); + const endpoint = `${wpUrl}/graphql`; + const { data } = await executeGraphQLHTTP>({ + query: AuthRefreshTokenDocument, + variables: { refreshToken }, + }, { endpoint }); + return data?.refreshToken?.authToken || undefined; + })(); + + refreshTokenPromises.set(refreshToken, refreshPromise); + + return refreshPromise.finally(() => { + const current = refreshTokenPromises.get(refreshToken); + if (current === refreshPromise) { + refreshTokenPromises.delete(refreshToken); + } + }); } // Get auth token from user session (refresh if needed)