fix and update
This commit is contained in:
@@ -711,6 +711,9 @@ function LoginPageContent() {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
await completePin(pendingSessionId, pin);
|
await completePin(pendingSessionId, pin);
|
||||||
|
setPendingSessionId(null);
|
||||||
|
setPin('');
|
||||||
|
finishLoginRedirect();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
const [pinError, setPinError] = React.useState<string | null>(null);
|
const [pinError, setPinError] = React.useState<string | null>(null);
|
||||||
const [bootstrapError, setBootstrapError] = React.useState<string | null>(null);
|
const [bootstrapError, setBootstrapError] = React.useState<string | null>(null);
|
||||||
const isPinLockedRef = React.useRef(false);
|
const isPinLockedRef = React.useRef(false);
|
||||||
|
const userIdRef = React.useRef<string | null | undefined>(null);
|
||||||
const refreshInFlightRef = React.useRef<Promise<void> | null>(null);
|
const refreshInFlightRef = React.useRef<Promise<void> | null>(null);
|
||||||
const initialBootstrapDoneRef = React.useRef(false);
|
const initialBootstrapDoneRef = React.useRef(false);
|
||||||
|
|
||||||
@@ -170,6 +171,10 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
isPinLockedRef.current = isPinLocked;
|
isPinLockedRef.current = isPinLocked;
|
||||||
}, [isPinLocked]);
|
}, [isPinLocked]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
userIdRef.current = user?.id;
|
||||||
|
}, [user?.id]);
|
||||||
|
|
||||||
const clearPinLock = React.useCallback(() => {
|
const clearPinLock = React.useCallback(() => {
|
||||||
setIsPinLocked(false);
|
setIsPinLocked(false);
|
||||||
setLockedSessionId(null);
|
setLockedSessionId(null);
|
||||||
@@ -193,7 +198,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
const activatePinLock = React.useCallback((sessionId: string) => {
|
const activatePinLock = React.useCallback((sessionId: string) => {
|
||||||
const resolvedSessionId = sessionId || window.localStorage.getItem(AUTH_SESSION_KEY);
|
const resolvedSessionId = sessionId || window.localStorage.getItem(AUTH_SESSION_KEY);
|
||||||
if (!resolvedSessionId) return;
|
if (!resolvedSessionId) return;
|
||||||
markPinIdleWatch(user?.id);
|
markPinIdleWatch(userIdRef.current);
|
||||||
setLockedSessionId(resolvedSessionId);
|
setLockedSessionId(resolvedSessionId);
|
||||||
setIsPinLocked(true);
|
setIsPinLocked(true);
|
||||||
setPinError(null);
|
setPinError(null);
|
||||||
@@ -206,36 +211,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
void syncFedcmSession(accessToken);
|
void syncFedcmSession(accessToken);
|
||||||
}
|
}
|
||||||
}, [user?.id]);
|
}, []);
|
||||||
|
|
||||||
const warmUpAndApplySession = React.useCallback(
|
|
||||||
async (accessToken: string) => {
|
|
||||||
setIsSessionReady(false);
|
|
||||||
setIsLoading(true);
|
|
||||||
setBootstrapError(null);
|
|
||||||
invalidateApiGatewayReady();
|
|
||||||
setIsApiReady(false);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await ensureApiGatewayReady();
|
|
||||||
const session = await fetchAuthSession(accessToken);
|
|
||||||
applySessionState(session, { setUser, setToken, activatePinLock, clearPinLock });
|
|
||||||
initialBootstrapDoneRef.current = true;
|
|
||||||
setIsApiReady(true);
|
|
||||||
setIsSessionReady(true);
|
|
||||||
} catch (error) {
|
|
||||||
setBootstrapError(
|
|
||||||
isGatewayUnavailableError(error)
|
|
||||||
? 'Не удалось подключиться к серверу API. Подождите несколько секунд и нажмите «Повторить».'
|
|
||||||
: (getApiErrorMessage(error, 'Не удалось подключиться к серверу API') ?? 'Ошибка подключения')
|
|
||||||
);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[activatePinLock, clearPinLock]
|
|
||||||
);
|
|
||||||
|
|
||||||
const establishSession = React.useCallback(
|
const establishSession = React.useCallback(
|
||||||
async (auth: AuthTokens) => {
|
async (auth: AuthTokens) => {
|
||||||
@@ -463,9 +439,12 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
return () => setPinRequiredHandler(null);
|
return () => setPinRequiredHandler(null);
|
||||||
}, [activatePinLock]);
|
}, [activatePinLock]);
|
||||||
|
|
||||||
|
const refreshProfileRef = React.useRef(refreshProfile);
|
||||||
|
refreshProfileRef.current = refreshProfile;
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
void refreshProfile();
|
void refreshProfileRef.current();
|
||||||
}, [refreshProfile]);
|
}, []);
|
||||||
|
|
||||||
const pinIdleLockEnabled =
|
const pinIdleLockEnabled =
|
||||||
isSessionReady &&
|
isSessionReady &&
|
||||||
@@ -523,6 +502,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
await establishSession(auth);
|
await establishSession(auth);
|
||||||
} else {
|
} else {
|
||||||
persistPartialAuth(auth);
|
persistPartialAuth(auth);
|
||||||
|
setUser(auth.user);
|
||||||
markPinIdleWatch(auth.user.id);
|
markPinIdleWatch(auth.user.id);
|
||||||
setHasStoredSession(true);
|
setHasStoredSession(true);
|
||||||
}
|
}
|
||||||
@@ -559,6 +539,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
await establishSession(response.auth);
|
await establishSession(response.auth);
|
||||||
} else if (response.auth) {
|
} else if (response.auth) {
|
||||||
persistPartialAuth(response.auth);
|
persistPartialAuth(response.auth);
|
||||||
|
setUser(response.auth.user);
|
||||||
markPinIdleWatch(response.auth.user.id);
|
markPinIdleWatch(response.auth.user.id);
|
||||||
setHasStoredSession(true);
|
setHasStoredSession(true);
|
||||||
}
|
}
|
||||||
@@ -581,6 +562,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
await establishSession(auth);
|
await establishSession(auth);
|
||||||
} else {
|
} else {
|
||||||
persistPartialAuth(auth);
|
persistPartialAuth(auth);
|
||||||
|
setUser(auth.user);
|
||||||
markPinIdleWatch(auth.user.id);
|
markPinIdleWatch(auth.user.id);
|
||||||
setHasStoredSession(true);
|
setHasStoredSession(true);
|
||||||
}
|
}
|
||||||
@@ -603,6 +585,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
await establishSession(auth);
|
await establishSession(auth);
|
||||||
} else {
|
} else {
|
||||||
persistPartialAuth(auth);
|
persistPartialAuth(auth);
|
||||||
|
setUser(auth.user);
|
||||||
markPinIdleWatch(auth.user.id);
|
markPinIdleWatch(auth.user.id);
|
||||||
setHasStoredSession(true);
|
setHasStoredSession(true);
|
||||||
}
|
}
|
||||||
@@ -632,6 +615,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
await establishSession(auth);
|
await establishSession(auth);
|
||||||
} else {
|
} else {
|
||||||
persistPartialAuth(auth);
|
persistPartialAuth(auth);
|
||||||
|
setUser(auth.user);
|
||||||
markPinIdleWatch(auth.user.id);
|
markPinIdleWatch(auth.user.id);
|
||||||
setHasStoredSession(true);
|
setHasStoredSession(true);
|
||||||
}
|
}
|
||||||
@@ -660,34 +644,48 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ sessionId, pin })
|
body: JSON.stringify({ sessionId, pin })
|
||||||
});
|
});
|
||||||
|
|
||||||
window.localStorage.setItem(AUTH_TOKEN_KEY, response.accessToken);
|
window.localStorage.setItem(AUTH_TOKEN_KEY, response.accessToken);
|
||||||
window.localStorage.setItem(AUTH_SESSION_KEY, sessionId);
|
window.localStorage.setItem(AUTH_SESSION_KEY, sessionId);
|
||||||
setToken(response.accessToken);
|
setToken(response.accessToken);
|
||||||
markPinIdleWatch(user?.id);
|
clearPinLock();
|
||||||
|
|
||||||
try {
|
|
||||||
await warmUpAndApplySession(response.accessToken);
|
|
||||||
} catch (error) {
|
|
||||||
if (!isGatewayUnavailableError(error)) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
const cachedUser = readCachedUserProfile();
|
const cachedUser = readCachedUserProfile();
|
||||||
|
markPinIdleWatch(userIdRef.current ?? cachedUser?.id);
|
||||||
if (cachedUser) {
|
if (cachedUser) {
|
||||||
setUser(cachedUser);
|
setUser(cachedUser);
|
||||||
}
|
}
|
||||||
clearPinLock();
|
setHasStoredSession(true);
|
||||||
setBootstrapError(null);
|
setBootstrapError(null);
|
||||||
initialBootstrapDoneRef.current = true;
|
initialBootstrapDoneRef.current = true;
|
||||||
setIsApiReady(true);
|
setIsApiReady(true);
|
||||||
setIsSessionReady(true);
|
setIsSessionReady(true);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
||||||
|
void fetchAuthSession(response.accessToken)
|
||||||
|
.then((session) => {
|
||||||
|
applySessionState(session, { setUser, setToken, activatePinLock, clearPinLock });
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (isPinRequiredError(error)) {
|
||||||
|
activatePinLock(error.sessionId ?? sessionId);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
if (!isGatewayUnavailableError(error)) {
|
||||||
|
const message = getApiErrorMessage(error, 'Не удалось обновить профиль после PIN');
|
||||||
|
if (message) showToast(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (isFedcmLoginPopup()) {
|
if (isFedcmLoginPopup()) {
|
||||||
await finalizeFedcmLogin(response.accessToken);
|
await finalizeFedcmLogin(response.accessToken);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onAuthEntryPage =
|
||||||
|
pathname.startsWith('/auth/login') || pathname.startsWith('/auth/register');
|
||||||
|
|
||||||
|
if (!onAuthEntryPage) {
|
||||||
const postPinRedirect =
|
const postPinRedirect =
|
||||||
typeof window !== 'undefined'
|
typeof window !== 'undefined'
|
||||||
? resolvePostPinAuthRedirect(pathname, window.location.search)
|
? resolvePostPinAuthRedirect(pathname, window.location.search)
|
||||||
@@ -705,9 +703,11 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
await finalizeFedcmLogin(response.accessToken);
|
await finalizeFedcmLogin(response.accessToken);
|
||||||
} else {
|
} else {
|
||||||
void syncFedcmSession(response.accessToken);
|
void syncFedcmSession(response.accessToken);
|
||||||
|
scheduleFedcmSessionSync(response.accessToken, 8000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[pathname, router, user?.id, warmUpAndApplySession]
|
[activatePinLock, clearPinLock, pathname, router, showToast]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePinUnlock = React.useCallback(
|
const handlePinUnlock = React.useCallback(
|
||||||
|
|||||||
Reference in New Issue
Block a user