import { type RouteLocationNormalized } from "vue-router" import { isEmpty, isNil } from "lodash" import useCurrentUser, { type UserAsShow } from "@/use/use-current-user" export async function authorizationGuard(to: RouteLocationNormalized) { const guardGroups = to.matched .map((record) => record.meta.guards as ((user: UserAsShow) => boolean)[] | undefined) .filter((g): g is ((user: UserAsShow) => boolean)[] => !isNil(g) && !isEmpty(g)) if (guardGroups.length === 0) return true const { currentUser, fetch } = useCurrentUser() if (isNil(currentUser.value)) { await fetch() } if (isNil(currentUser.value)) { throw new Error("No current user") } // AND across matched records (every level must pass), OR within each // record's guards array (any guard at that level satisfies it). for (const guards of guardGroups) { const passes = guards.some((guard) => { if (typeof guard !== "function") { throw new Error(`Guard ${guard} is not a function`) } return guard(currentUser.value as UserAsShow) }) if (!passes) return false } return true } export default authorizationGuard