import { computed, watch } from 'vue' import router from '@/router' import { authenticateWithFingerprint, getToken, isIphone, removeToken } from '@/utils' import { useUserStore } from '@/store/userStore' import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router' import { useAuthStore } from '@/store/useAuthStore' import { clearFingerTimeout, getFingerPosition, getHasFingerPrint, setFingerPosition, setFingerTimeOut, setHasFingerPrint } from '@/app/authBoot' import { recoverMobileViewportAfterAuth } from '@/layouts/composables/useMobileScrollReset' export function setupRouterGuards() { const userStore = useUserStore() const authStore = useAuthStore() const isApple: boolean = isIphone() let isFirst = true const currentRoute = computed(() => router.currentRoute.value.fullPath) async function start() { if (!getToken()) { return } if (!userStore.userInfo) { await userStore.getMyInfo() } } function isGuestAllowed(to: RouteLocationNormalized) { if (to.meta?.public) { return true } return ['login', '404', 'buyProduct', 'productDetail', 'about', 'aboutSoftware', 'cart', 'tvMonitor'].includes( to.name as string, ) } function goToLogin(to: RouteLocationNormalized, next: NavigationGuardNext) { if (isGuestAllowed(to)) { return next() } if (to.name !== 'login') { return next({ name: 'login' }) } return next() } function goToHome(to: RouteLocationNormalized, next: NavigationGuardNext) { if (to.name !== 'buyProduct') { return next({ name: 'buyProduct' }) } return next() } router.beforeEach(async (to, from, next) => { authStore.setLoading(true) clearFingerTimeout() if (to.name !== 'tvMonitor' && !to.meta?.hideChrome) { setFingerTimeOut(to) } if (to.name === 'notifyTrigger' && getToken()) { const { useSettingsStore } = await import('@/store/settingsStore') const settingsStore = useSettingsStore() if (!settingsStore.loaded) { await settingsStore.fetchSettings() } if (!settingsStore.isSettingTruthy('has_page_price_trigger')) { return next({ name: (from.name as string) || 'user' }) } } if (to.name === 'appNotifications' && getToken()) { const { useSettingsStore } = await import('@/store/settingsStore') const settingsStore = useSettingsStore() if (!settingsStore.loaded) { await settingsStore.fetchSettings() } if (!settingsStore.isSettingTruthy('has_page_notification')) { return next({ name: (from.name as string) || 'home' }) } } if (to.name === 'giftCard' && getToken()) { const { useSettingsStore } = await import('@/store/settingsStore') const settingsStore = useSettingsStore() if (!settingsStore.loaded) { await settingsStore.fetchSettings() } if (!settingsStore.isSettingTruthy('has_page_gift_card')) { return next({ name: (from.name as string) || 'user' }) } } if (isFirst) { isFirst = false if (getToken()) { await userStore.getMyInfo() const finger_print = userStore.userInfo.finger_print setHasFingerPrint(finger_print) if (isApple && finger_print) { removeToken() goToLogin(to, next) } else if (!isApple && finger_print) { setFingerPosition(await authenticateWithFingerprint()) if (!getFingerPosition()) { goToLogin(to, next) } } else { if (to.name == 'login') { goToHome(to, next) } return next() } } else { if (isGuestAllowed(to)) { return next() } goToLogin(to, next) } } else { if (getFingerPosition()) { if (getToken()) { if (to.name === 'login') { return next({ name: from.name || 'buyProduct' }) } return next() } if (isGuestAllowed(to)) { return next() } return next({ name: 'login' }) } if (getToken() && !getHasFingerPrint()) { next() } else { goToLogin(to, next) } } }) router.afterEach((to, from) => { if (document.documentElement.classList.contains('app-layout--desktop')) return if (from.name === 'login') { recoverMobileViewportAfterAuth() } }) watch(currentRoute, async () => (userStore.userInfo ? '' : await start())) }