fix and update
This commit is contained in:
@@ -107,15 +107,13 @@ function applySessionState(
|
||||
|
||||
function readInitialAuthState() {
|
||||
if (typeof window === 'undefined') {
|
||||
return { token: null as string | null, hasStoredSession: false, cachedUser: null as PublicUser | null };
|
||||
return { token: null as string | null, hasStoredSession: false };
|
||||
}
|
||||
const token = window.localStorage.getItem(AUTH_TOKEN_KEY);
|
||||
const refresh = window.localStorage.getItem(AUTH_REFRESH_KEY);
|
||||
const cachedUser = readCachedUserProfile();
|
||||
return {
|
||||
token,
|
||||
hasStoredSession: Boolean(refresh || token),
|
||||
cachedUser
|
||||
hasStoredSession: Boolean(refresh || token)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -125,7 +123,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
const { showToast } = useToast();
|
||||
const initialAuth = React.useMemo(() => readInitialAuthState(), []);
|
||||
const [token, setToken] = React.useState<string | null>(initialAuth.token);
|
||||
const [user, setUser] = React.useState<PublicUser | null>(initialAuth.cachedUser);
|
||||
const [user, setUser] = React.useState<PublicUser | null>(null);
|
||||
const [isLoading, setIsLoading] = React.useState(true);
|
||||
const [isApiReady, setIsApiReady] = React.useState(false);
|
||||
const [isSessionReady, setIsSessionReady] = React.useState(false);
|
||||
@@ -269,8 +267,12 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
setHasStoredSession(Boolean(refreshToken));
|
||||
|
||||
if (!currentToken && !refreshToken) {
|
||||
window.localStorage.removeItem(AUTH_USER_CACHE_KEY);
|
||||
setUser(null);
|
||||
setToken(null);
|
||||
initialBootstrapDoneRef.current = true;
|
||||
setIsSessionReady(true);
|
||||
setIsApiReady(true);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
@@ -282,7 +284,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
|
||||
try {
|
||||
for (let bootstrapAttempt = 0; bootstrapAttempt < 6; bootstrapAttempt += 1) {
|
||||
for (let bootstrapAttempt = 0; bootstrapAttempt < 4; bootstrapAttempt += 1) {
|
||||
try {
|
||||
if (isInitialBootstrap) {
|
||||
await waitForStableGateway(3);
|
||||
@@ -293,11 +295,14 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
try {
|
||||
const session = await fetchAuthSession(currentToken);
|
||||
applySessionState(session, { setUser, setToken, activatePinLock, clearPinLock });
|
||||
setIsApiReady(true);
|
||||
setIsSessionReady(true);
|
||||
return;
|
||||
} catch (error) {
|
||||
if (isPinRequiredError(error)) {
|
||||
activatePinLock(error.sessionId ?? window.localStorage.getItem(AUTH_SESSION_KEY) ?? '');
|
||||
setIsApiReady(true);
|
||||
setIsSessionReady(true);
|
||||
return;
|
||||
}
|
||||
if (!(error instanceof ApiError) || error.code !== 'TOKEN_EXPIRED') {
|
||||
@@ -321,11 +326,14 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
cacheUserProfile(refreshed.user);
|
||||
}
|
||||
activatePinLock(refreshed.sessionId ?? '');
|
||||
setIsApiReady(true);
|
||||
setIsSessionReady(true);
|
||||
return;
|
||||
}
|
||||
if (refreshed.accessToken) {
|
||||
const session = await fetchAuthSession(refreshed.accessToken);
|
||||
applySessionState(session, { setUser, setToken, activatePinLock, clearPinLock });
|
||||
setIsApiReady(true);
|
||||
setIsSessionReady(true);
|
||||
return;
|
||||
}
|
||||
@@ -333,17 +341,26 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
throw new ApiError('Сессия недействительна', 401);
|
||||
} catch (error) {
|
||||
if (isGatewayUnavailableError(error) && isInitialBootstrap && bootstrapAttempt + 1 < 6) {
|
||||
if (isGatewayUnavailableError(error) && isInitialBootstrap && bootstrapAttempt + 1 < 4) {
|
||||
invalidateApiGatewayReady();
|
||||
if (bootstrapAttempt >= 1) {
|
||||
setBootstrapError(
|
||||
'Не удалось подключиться к серверу API (502). Подождите несколько секунд и нажмите «Повторить».'
|
||||
);
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 1200));
|
||||
continue;
|
||||
}
|
||||
if (isPinRequiredError(error)) {
|
||||
activatePinLock(error.sessionId ?? window.localStorage.getItem(AUTH_SESSION_KEY) ?? '');
|
||||
setIsApiReady(true);
|
||||
setIsSessionReady(true);
|
||||
return;
|
||||
}
|
||||
if (refreshToken && error instanceof ApiError && error.status === 403) {
|
||||
activatePinLock(window.localStorage.getItem(AUTH_SESSION_KEY) ?? '');
|
||||
setIsApiReady(true);
|
||||
setIsSessionReady(true);
|
||||
return;
|
||||
}
|
||||
if (error instanceof ApiError && (error.code === 'NO_REFRESH' || error.status === 401)) {
|
||||
@@ -612,7 +629,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
const isBootstrapping =
|
||||
!isPinLocked &&
|
||||
Boolean(hasStoredSession || token || user) &&
|
||||
Boolean(hasStoredSession || token) &&
|
||||
(isLoading || !isApiReady || !isSessionReady);
|
||||
|
||||
return (
|
||||
@@ -649,6 +666,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
? () => {
|
||||
setBootstrapError(null);
|
||||
initialBootstrapDoneRef.current = false;
|
||||
invalidateApiGatewayReady();
|
||||
void refreshProfile();
|
||||
}
|
||||
: undefined
|
||||
|
||||
Reference in New Issue
Block a user