fix: wait until everything is loaded before replacing the current view with the last or login view
This commit is contained in:
parent
3f04571e43
commit
6083301d1f
@ -61,7 +61,7 @@ const route = useRoute()
|
|||||||
|
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
|
|
||||||
const ready = ref(false)
|
const ready = computed(() => baseStore.ready)
|
||||||
const online = useOnline()
|
const online = useOnline()
|
||||||
|
|
||||||
const error = ref('')
|
const error = ref('')
|
||||||
@ -70,11 +70,11 @@ const showLoading = computed(() => !ready.value && error.value === '')
|
|||||||
async function load() {
|
async function load() {
|
||||||
try {
|
try {
|
||||||
await baseStore.loadApp()
|
await baseStore.loadApp()
|
||||||
const redirectTo = getAuthForRoute(route)
|
baseStore.setReady(true)
|
||||||
|
const redirectTo = await getAuthForRoute(route)
|
||||||
if (typeof redirectTo !== 'undefined') {
|
if (typeof redirectTo !== 'undefined') {
|
||||||
await router.push(redirectTo)
|
await router.push(redirectTo)
|
||||||
}
|
}
|
||||||
ready.value = true
|
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
error.value = String(e)
|
error.value = String(e)
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ export function useRenewTokenOnFocus() {
|
|||||||
authStore.renewToken()
|
authStore.renewToken()
|
||||||
|
|
||||||
// Check if the token is still valid if the window gets focus again to maybe renew it
|
// Check if the token is still valid if the window gets focus again to maybe renew it
|
||||||
useEventListener('focus', () => {
|
useEventListener('focus', async () => {
|
||||||
if (!authenticated.value) {
|
if (!authenticated.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -26,8 +26,8 @@ export function useRenewTokenOnFocus() {
|
|||||||
// If the token expiry is negative, it is already expired and we have no choice but to redirect
|
// If the token expiry is negative, it is already expired and we have no choice but to redirect
|
||||||
// the user to the login page
|
// the user to the login page
|
||||||
if (expiresIn < 0) {
|
if (expiresIn < 0) {
|
||||||
authStore.checkAuth()
|
await authStore.checkAuth()
|
||||||
router.push({name: 'user.login'})
|
await router.push({name: 'user.login'})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import {setTitle} from '@/helpers/setTitle'
|
|||||||
|
|
||||||
import {useListStore} from '@/stores/lists'
|
import {useListStore} from '@/stores/lists'
|
||||||
import {useAuthStore} from '@/stores/auth'
|
import {useAuthStore} from '@/stores/auth'
|
||||||
|
import {useBaseStore} from '@/stores/base'
|
||||||
|
|
||||||
import HomeComponent from '../views/Home.vue'
|
import HomeComponent from '../views/Home.vue'
|
||||||
import NotFoundComponent from '../views/404.vue'
|
import NotFoundComponent from '../views/404.vue'
|
||||||
@ -464,11 +465,18 @@ const router = createRouter({
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
export function getAuthForRoute(route: RouteLocation) {
|
export async function getAuthForRoute(route: RouteLocation) {
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
if (authStore.authUser || authStore.authLinkShare) {
|
if (authStore.authUser || authStore.authLinkShare) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const baseStore = useBaseStore()
|
||||||
|
// When trying this before the current user was fully loaded we might get a flash of the login screen
|
||||||
|
// in the user shell. To make shure this does not happen we check if everything is ready before trying.
|
||||||
|
if (!baseStore.ready) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the user is already logged in and redirect them to the home page if not
|
// Check if the user is already logged in and redirect them to the home page if not
|
||||||
if (
|
if (
|
||||||
@ -497,7 +505,7 @@ export function getAuthForRoute(route: RouteLocation) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
router.beforeEach((to) => {
|
router.beforeEach(async (to) => {
|
||||||
return getAuthForRoute(to)
|
return getAuthForRoute(to)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
saveToken(response.data.token, true)
|
saveToken(response.data.token, true)
|
||||||
|
|
||||||
// Tell others the user is autheticated
|
// Tell others the user is autheticated
|
||||||
this.checkAuth()
|
await this.checkAuth()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (
|
if (
|
||||||
e.response &&
|
e.response &&
|
||||||
@ -168,7 +168,7 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
saveToken(response.data.token, true)
|
saveToken(response.data.token, true)
|
||||||
|
|
||||||
// Tell others the user is autheticated
|
// Tell others the user is autheticated
|
||||||
this.checkAuth()
|
await this.checkAuth()
|
||||||
} finally {
|
} finally {
|
||||||
this.setIsLoading(false)
|
this.setIsLoading(false)
|
||||||
}
|
}
|
||||||
@ -180,12 +180,12 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
password: password,
|
password: password,
|
||||||
})
|
})
|
||||||
saveToken(response.data.token, false)
|
saveToken(response.data.token, false)
|
||||||
this.checkAuth()
|
await this.checkAuth()
|
||||||
return response.data
|
return response.data
|
||||||
},
|
},
|
||||||
|
|
||||||
// Populates user information from jwt token saved in local storage in store
|
// Populates user information from jwt token saved in local storage in store
|
||||||
checkAuth() {
|
async checkAuth() {
|
||||||
|
|
||||||
// This function can be called from multiple places at the same time and shortly after one another.
|
// This function can be called from multiple places at the same time and shortly after one another.
|
||||||
// To prevent hitting the api too frequently or race conditions, we check at most once per minute.
|
// To prevent hitting the api too frequently or race conditions, we check at most once per minute.
|
||||||
@ -209,7 +209,7 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
this.setUser(info)
|
this.setUser(info)
|
||||||
|
|
||||||
if (authenticated) {
|
if (authenticated) {
|
||||||
this.refreshUserInfo()
|
await this.refreshUserInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,6 +218,8 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
this.setUser(null)
|
this.setUser(null)
|
||||||
this.redirectToProviderIfNothingElseIsEnabled()
|
this.redirectToProviderIfNothingElseIsEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Promise.resolve(authenticated)
|
||||||
},
|
},
|
||||||
|
|
||||||
redirectToProviderIfNothingElseIsEnabled() {
|
redirectToProviderIfNothingElseIsEnabled() {
|
||||||
@ -335,22 +337,22 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await refreshToken(!this.isLinkShareAuth)
|
await refreshToken(!this.isLinkShareAuth)
|
||||||
this.checkAuth()
|
await this.checkAuth()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Don't logout on network errors as the user would then get logged out if they don't have
|
// Don't logout on network errors as the user would then get logged out if they don't have
|
||||||
// internet for a short period of time - such as when the laptop is still reconnecting
|
// internet for a short period of time - such as when the laptop is still reconnecting
|
||||||
if (e?.request?.status) {
|
if (e?.request?.status) {
|
||||||
this.logout()
|
await this.logout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 5000)
|
}, 5000)
|
||||||
},
|
},
|
||||||
|
|
||||||
logout() {
|
async logout() {
|
||||||
removeToken()
|
removeToken()
|
||||||
window.localStorage.clear() // Clear all settings and history we might have saved in local storage.
|
window.localStorage.clear() // Clear all settings and history we might have saved in local storage.
|
||||||
router.push({name: 'user.login'})
|
await router.push({name: 'user.login'})
|
||||||
this.checkAuth()
|
await this.checkAuth()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -11,6 +11,7 @@ import type {IList} from '@/modelTypes/IList'
|
|||||||
|
|
||||||
export interface RootStoreState {
|
export interface RootStoreState {
|
||||||
loading: boolean,
|
loading: boolean,
|
||||||
|
ready: boolean,
|
||||||
|
|
||||||
currentList: IList | null,
|
currentList: IList | null,
|
||||||
background: string,
|
background: string,
|
||||||
@ -26,6 +27,7 @@ export interface RootStoreState {
|
|||||||
export const useBaseStore = defineStore('base', {
|
export const useBaseStore = defineStore('base', {
|
||||||
state: () : RootStoreState => ({
|
state: () : RootStoreState => ({
|
||||||
loading: false,
|
loading: false,
|
||||||
|
ready: false,
|
||||||
|
|
||||||
// This is used to highlight the current list in menu for all list related views
|
// This is used to highlight the current list in menu for all list related views
|
||||||
currentList: new ListModel({
|
currentList: new ListModel({
|
||||||
@ -95,6 +97,10 @@ export const useBaseStore = defineStore('base', {
|
|||||||
setLogoVisible(visible: boolean) {
|
setLogoVisible(visible: boolean) {
|
||||||
this.logoVisible = visible
|
this.logoVisible = visible
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setReady(ready: boolean) {
|
||||||
|
this.ready = ready
|
||||||
|
},
|
||||||
|
|
||||||
async handleSetCurrentList({list, forceUpdate = false} : {list: IList | null, forceUpdate: boolean}) {
|
async handleSetCurrentList({list, forceUpdate = false} : {list: IList | null, forceUpdate: boolean}) {
|
||||||
if (list === null) {
|
if (list === null) {
|
||||||
@ -133,7 +139,8 @@ export const useBaseStore = defineStore('base', {
|
|||||||
|
|
||||||
async loadApp() {
|
async loadApp() {
|
||||||
await checkAndSetApiUrl(window.API_URL)
|
await checkAndSetApiUrl(window.API_URL)
|
||||||
useAuthStore().checkAuth()
|
await useAuthStore().checkAuth()
|
||||||
|
this.ready = true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user