Fix infinite loading

- Reset "requires auth" flag in session storage for reset on tab refresh
- Fix context los for resolving, rejecting queued request
- Process queued requests after successful login

Regression 6636cc66b1

fixes #1028
This commit is contained in:
schroda
2025-10-15 22:34:11 +02:00
parent 6636cc66b1
commit 0ffb54e2cc
3 changed files with 18 additions and 5 deletions

View File

@@ -6,7 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
import { ReactNode } from 'react'; import { ReactNode, useEffect } from 'react';
import { useSessionContext } from '@/features/authentication/SessionContext.tsx'; import { useSessionContext } from '@/features/authentication/SessionContext.tsx';
import { SplashScreen } from '@/features/authentication/components/SplashScreen.tsx'; import { SplashScreen } from '@/features/authentication/components/SplashScreen.tsx';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
@@ -28,6 +28,15 @@ export const AuthGuard = ({ children }: { children: ReactNode }) => {
}, },
}); });
useEffect(() => {
const handleUnload = () => {
AuthManager.setAuthRequired(null);
};
window.addEventListener('beforeunload', handleUnload);
return () => window.removeEventListener('beforeunload', handleUnload);
}, []);
if (isAuthRequired === null) { if (isAuthRequired === null) {
return <SplashScreen />; return <SplashScreen />;
} }

View File

@@ -47,6 +47,7 @@ export const LoginPage = () => {
if (data) { if (data) {
AuthManager.setTokens(data.login.accessToken, data.login.refreshToken); AuthManager.setTokens(data.login.accessToken, data.login.refreshToken);
requestManager.processQueues();
navigate(redirect ?? AppRoutes.root.path); navigate(redirect ?? AppRoutes.root.path);
} }
} catch (e) { } catch (e) {

View File

@@ -39,7 +39,8 @@ export abstract class BaseClient<Client, ClientConfig, Fetcher> {
): Promise<UserRefreshMutation | null | undefined> { ): Promise<UserRefreshMutation | null | undefined> {
const refreshToken = AuthManager.getRefreshToken(); const refreshToken = AuthManager.getRefreshToken();
if (!AuthManager.isAuthRequired()) { if (!AuthManager.isAuthInitialized()) {
AuthManager.setAuthInitialized(true);
AuthManager.setAuthRequired(true); AuthManager.setAuthRequired(true);
} }
@@ -65,7 +66,6 @@ export abstract class BaseClient<Client, ClientConfig, Fetcher> {
} }
AuthManager.setAccessToken(data.refreshToken.accessToken); AuthManager.setAccessToken(data.refreshToken.accessToken);
AuthManager.setAuthInitialized(true);
BaseClient.onTokenRefreshComplete?.(); BaseClient.onTokenRefreshComplete?.();
@@ -106,7 +106,10 @@ export abstract class BaseClient<Client, ClientConfig, Fetcher> {
return executor(); return executor();
} }
const { promise: requestPromise, reject, resolve } = new ControlledPromise<T>(); const queuedRequest = new ControlledPromise<T>();
const resolve = queuedRequest.resolve.bind(queuedRequest);
const reject = queuedRequest.reject.bind(queuedRequest);
this.requestQueue.push({ this.requestQueue.push({
execute: () => { execute: () => {
executor().then(resolve).catch(reject); executor().then(resolve).catch(reject);
@@ -115,7 +118,7 @@ export abstract class BaseClient<Client, ClientConfig, Fetcher> {
reject, reject,
}); });
return requestPromise; return queuedRequest.promise;
} }
public processQueue(): void { public processQueue(): void {