fix(web): skip GetCurrentUser on init when no token is stored

When no token exists in sessionStorage, AuthContext.initialize() was
still calling GetCurrentUser, triggering the auth interceptor to attempt
RefreshToken and retry — producing a burst of 5+ auth API calls in under
a second that reverse proxies with rate limiting (e.g. CrowdSec) flag as
brute force.

Add hasStoredToken() to auth-state and bail out of initialize() early
when there is definitively no session to restore. The refresh flow for
expired tokens is preserved since hasStoredToken() checks for presence
regardless of expiry.

Fixes #5647
pull/5654/head
Steven 3 months ago
parent b8bca6bacf
commit 4aaebc507e

@ -62,6 +62,19 @@ export const isTokenExpired = (bufferMs: number = 30000): boolean => {
return new Date() >= new Date(tokenExpiresAt.getTime() - bufferMs);
};
// Returns true if a token exists in sessionStorage, even if it is expired.
// Used to decide whether to attempt GetCurrentUser on app init — if no token
// was ever stored, the user is definitively not logged in and there is nothing
// to refresh, so we can skip the network round-trip entirely.
export const hasStoredToken = (): boolean => {
if (accessToken) return true;
try {
return !!sessionStorage.getItem(SESSION_TOKEN_KEY);
} catch {
return false;
}
};
export const clearAccessToken = (): void => {
accessToken = null;
tokenExpiresAt = null;

@ -1,6 +1,6 @@
import { useQueryClient } from "@tanstack/react-query";
import { createContext, type ReactNode, useCallback, useContext, useMemo, useState } from "react";
import { clearAccessToken } from "@/auth-state";
import { clearAccessToken, hasStoredToken } from "@/auth-state";
import { authServiceClient, shortcutServiceClient, userServiceClient } from "@/connect";
import { userKeys } from "@/hooks/useUserQueries";
import type { Shortcut } from "@/types/proto/api/v1/shortcut_service_pb";
@ -52,6 +52,21 @@ export function AuthProvider({ children }: { children: ReactNode }) {
const initialize = useCallback(async () => {
setState((prev) => ({ ...prev, isLoading: true }));
// If there is no stored token at all, the user is not authenticated.
// Skip the network call — there is nothing to refresh and no session to restore.
if (!hasStoredToken()) {
setState({
currentUser: undefined,
userGeneralSetting: undefined,
userWebhooksSetting: undefined,
shortcuts: [],
isInitialized: true,
isLoading: false,
});
return;
}
try {
const { user: currentUser } = await authServiceClient.getCurrentUser({});

Loading…
Cancel
Save