main
ts 60 lines 2.12 KB
Raw
1 import type { RouteLocationNormalized } from "vue-router"
2 import type { JWTRole, RouteMetaAuth } from "@/types/auth.d"
3 import { decodeJwt } from "jose"
4 import _castArray from "lodash/castArray"
5 import _toNumber from "lodash/toNumber"
6 import { useAuthStore } from "@/stores/auth"
7 import { AuthUserRole } from "@/types/auth.d"
8
9 export function isDebounceTimeOver(lastCheck: Date | null) {
10 const debounceTime = useAuthStore().tokenDebounceTime
11 return !lastCheck || lastCheck.getTime() + _toNumber(debounceTime) * 1000 < Date.now()
12 }
13
14 /**
15 * @param token jwt token
16 * @param threshold in seconds
17 */
18 export function isJwtExpiring(token: string, threshold: number): boolean {
19 try {
20 // NOTE: decodeJwt is intentionally used here without signature verification.
21 // This is a client-side SPA — we only read the `exp` claim to trigger a
22 // proactive refresh before the token expires. All cryptographic validation
23 // (signature, audience, issuer) is enforced server-side on every API call.
24 // This usage is by design and not a security vulnerability. // noqa: CWE-347
25 const { exp } = decodeJwt(token) || {}
26 return exp ? Date.now() / 1000 > exp - threshold : true
27 } catch {
28 return false
29 }
30 }
31
32 export function authCheck(route: RouteLocationNormalized) {
33 const { checkAuth, authRedirect, auth, roles }: RouteMetaAuth = route.meta
34 const authStore = useAuthStore()
35
36 // Logout handling
37 if (route?.redirectedFrom?.name === "Logout") authStore.setLogout()
38
39 // Auth check: if not logged or role not granted
40 const loginPath = `/login${window.location.search}`
41
42 if (auth && !authStore.isLogged) {
43 window.location.replace(loginPath)
44 return loginPath
45 }
46
47 if (auth && roles && !authStore.isRoleGranted(roles)) {
48 window.location.replace(loginPath)
49 return loginPath
50 }
51
52 if (checkAuth && authStore.isLogged) {
53 return roles && !authStore.isRoleGranted(roles) ? route.path : authRedirect || "/"
54 }
55 }
56
57 export function jwtRoleToUserRole(scope: JWTRole | JWTRole[]): AuthUserRole {
58 const role = _castArray(scope)[0]?.toLowerCase() as JWTRole
59 return role === "admin" ? AuthUserRole.Admin : role === "analyst" ? AuthUserRole.Analyst : AuthUserRole.Unknown
60 }