import { computed, watch } from 'vue' import router from '@/router' import { authenticateWithFingerprint, getToken, isIphone, removeToken } from '@/utils' import { useUserStore } from '@/store/userStore' import { useWalletStore } from '@/store/walletStore' 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' import { getDefaultLandingRoute, hasAbshodeTrading, hasHomePage, hasProductShop, } from '@/config/project-profile' const GUEST_PUBLIC_ROUTES = ['login', '404', 'about', 'cart'] as const function getGuestPublicRoutes(): string[] { const routes: string[] = [...GUEST_PUBLIC_ROUTES] if (hasProductShop()) { routes.push('buyProduct', 'productDetail') } return routes } function enforceProjectRouteAccess( to: RouteLocationNormalized, next: NavigationGuardNext ): boolean { if (!hasHomePage() && to.name === 'home') { next({ name: getDefaultLandingRoute() }) return true } if (!hasAbshodeTrading() && to.name === 'gold') { next({ name: getDefaultLandingRoute() }) return true } if (!hasProductShop() && (to.name === 'buyProduct' || to.name === 'productDetail')) { next({ name: getDefaultLandingRoute() }) return true } return false } export function setupRouterGuards() { const userStore = useUserStore() const walletStore = useWalletStore() const authStore = useAuthStore() const isApple: boolean = isIphone() let isFirst = true const currentRoute = computed(() => router.currentRoute.value.fullPath) async function start() { if (!getToken()) { return } const tasks: Promise[] = [ walletStore.getLimitedPrice(), walletStore.getLimitedBuyGold(), ] if (!userStore.userInfo) { tasks.push(userStore.getMyInfo()) } await Promise.all(tasks) } function goToLogin(to: RouteLocationNormalized, next: NavigationGuardNext) { if (getGuestPublicRoutes().includes(to.name as string)) { return next() } if (to.name !== 'login') { return next({ name: 'login' }) } return next() } function goToLanding(to: RouteLocationNormalized, next: NavigationGuardNext) { const landing = getDefaultLandingRoute() if (to.name !== landing) { return next({ name: landing }) } return next() } router.beforeEach(async (to, from, next) => { authStore.setLoading(true) clearFingerTimeout() setFingerTimeOut(to) if (enforceProjectRouteAccess(to, next)) { return } 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') { return goToLanding(to, next) } if (enforceProjectRouteAccess(to, next)) { return } return next() } } else { if (getGuestPublicRoutes().includes(to.name as string)) { return next() } goToLogin(to, next) } } else { if (getFingerPosition()) { if (getToken()) { if (to.name === 'login') { return next({ name: (from.name as string) || getDefaultLandingRoute() }) } if (enforceProjectRouteAccess(to, next)) { return } return next() } if (getGuestPublicRoutes().includes(to.name as string)) { return next() } return next({ name: 'login' }) } if (getToken() && !getHasFingerPrint()) { if (enforceProjectRouteAccess(to, next)) { return } 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())) }