🐛(sso) prevent flash when trying to autologin
the issue was we return the fetchUser promise to react query too early (before the browser reloaded the page). now we make sure react query doesn't get the info
This commit is contained in:
committed by
aleb_the_flash
parent
234116163a
commit
fdff5092b0
@@ -1,7 +1,7 @@
|
||||
import { ApiError } from '@/api/ApiError'
|
||||
import { fetchApi } from '@/api/fetchApi'
|
||||
import { type ApiUser } from './ApiUser'
|
||||
import { attemptSilentLogin } from "@/features/auth";
|
||||
import { attemptSilentLogin, canAttemptSilentLogin } from '../utils/silentLogin'
|
||||
|
||||
/**
|
||||
* fetch the logged-in user from the api.
|
||||
@@ -17,8 +17,13 @@ export const fetchUser = (): Promise<ApiUser | false> => {
|
||||
.catch((error) => {
|
||||
// we assume that a 401 means the user is not logged in
|
||||
if (error instanceof ApiError && error.statusCode === 401) {
|
||||
attemptSilentLogin(3600)
|
||||
resolve(false)
|
||||
// make sure to not resolve the promise while trying to silent login
|
||||
// so that consumers of fetchUser don't think the work already ended
|
||||
if (canAttemptSilentLogin()) {
|
||||
attemptSilentLogin(3600)
|
||||
} else {
|
||||
resolve(false)
|
||||
}
|
||||
} else {
|
||||
reject(error)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { keys } from '@/api/queryKeys'
|
||||
import { fetchUser } from './fetchUser'
|
||||
import { type ApiUser } from './ApiUser'
|
||||
|
||||
/**
|
||||
* returns info about currently logged in user
|
||||
@@ -13,14 +14,13 @@ export const useUser = () => {
|
||||
queryFn: fetchUser,
|
||||
})
|
||||
|
||||
let isLoggedIn = undefined
|
||||
if (query.data !== undefined) {
|
||||
isLoggedIn = query.data !== false
|
||||
}
|
||||
const isLoggedIn =
|
||||
query.status === 'success' ? query.data !== false : undefined
|
||||
const isLoggedOut = isLoggedIn === false
|
||||
|
||||
return {
|
||||
...query,
|
||||
// if fetchUser returns false, it means the user is not logged in: expose that
|
||||
user: query.data === false ? undefined : query.data,
|
||||
user: isLoggedOut ? undefined : (query.data as ApiUser | undefined),
|
||||
isLoggedIn,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,3 @@ export { useUser } from './api/useUser'
|
||||
export { authUrl } from './utils/authUrl'
|
||||
export { logoutUrl } from './utils/logoutUrl'
|
||||
export { RenderIfUserFetched } from './components/RenderIfUserFetched'
|
||||
export { attemptSilentLogin } from './utils/silentLogin'
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { apiUrl } from '@/api/apiUrl'
|
||||
|
||||
export const authUrl = (silent = false, returnTo = window.location.href) => {
|
||||
export const authUrl = ({
|
||||
silent = false,
|
||||
returnTo = window.location.href,
|
||||
} = {}) => {
|
||||
return apiUrl(`/authenticate?silent=${encodeURIComponent(silent)}&returnTo=${encodeURIComponent(returnTo)}`)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,11 @@ const setNextRetryTime = (retryIntervalInSeconds: number) => {
|
||||
}
|
||||
|
||||
const initiateSilentLogin = () => {
|
||||
window.location.href = authUrl(true)
|
||||
window.location.href = authUrl({ silent: true })
|
||||
}
|
||||
|
||||
export const canAttemptSilentLogin = () => {
|
||||
return isRetryAllowed()
|
||||
}
|
||||
|
||||
export const attemptSilentLogin = (retryIntervalInSeconds: number) => {
|
||||
|
||||
Reference in New Issue
Block a user