{"version":3,"file":"index.mjs","sources":["../src/crypto.ts","../src/guards/globalGuard.ts","../src/guards/createGuard.ts","../src/composables/usePermission.ts"],"sourcesContent":["import CryptoJS from \"crypto-js\";\n\nexport interface EncryptedPayload {\n  iv: string;\n  data: string;\n}\n\nexport interface PermissionCrypto {\n  encrypt<T>(value: T): EncryptedPayload;\n  decrypt<T = unknown>(payload: unknown): T | null;\n  decryptAuthPayload<T extends Record<string, any>>(\n    payload: T,\n    fields?: readonly string[],\n  ): T;\n}\n\nfunction normalizeSecret(rawSecret: string): string {\n  if (!rawSecret || typeof rawSecret !== \"string\") {\n    throw new Error(\"A crypto secret is required\");\n  }\n\n  const secret = rawSecret.trim();\n  if (secret.startsWith('\"') && secret.endsWith('\"')) {\n    return secret.slice(1, -1);\n  }\n\n  return secret;\n}\n\nfunction createKey(rawSecret: string): CryptoJS.lib.WordArray {\n  const key = CryptoJS.enc.Utf8.parse(normalizeSecret(rawSecret));\n  key.sigBytes = 32;\n  key.words.length = 8;\n  return key;\n}\n\nfunction parseEncryptedPayload(payload: unknown): EncryptedPayload | null {\n  if (payload && typeof payload === \"object\") {\n    const candidate = payload as Partial<EncryptedPayload>;\n    if (typeof candidate.iv === \"string\" && typeof candidate.data === \"string\") {\n      return candidate as EncryptedPayload;\n    }\n  }\n\n  if (typeof payload === \"string\") {\n    try {\n      return parseEncryptedPayload(JSON.parse(payload));\n    } catch {\n      return null;\n    }\n  }\n\n  return null;\n}\n\n/**\n * Creates an AES-CBC helper compatible with the encrypted permission payloads\n * returned by Jervis authentication APIs.\n */\nexport function createPermissionCrypto(rawSecret: string): PermissionCrypto {\n  const key = createKey(rawSecret);\n\n  const encrypt = <T>(value: T): EncryptedPayload => {\n    const iv = CryptoJS.lib.WordArray.random(16);\n    const encrypted = CryptoJS.AES.encrypt(JSON.stringify(value), key, {\n      iv,\n      mode: CryptoJS.mode.CBC,\n      padding: CryptoJS.pad.Pkcs7,\n    });\n\n    return {\n      iv: CryptoJS.enc.Base64.stringify(iv),\n      data: CryptoJS.enc.Base64.stringify(encrypted.ciphertext),\n    };\n  };\n\n  const decrypt = <T = unknown>(payload: unknown): T | null => {\n    try {\n      const encryptedPayload = parseEncryptedPayload(payload);\n      if (!encryptedPayload) return null;\n\n      const decrypted = CryptoJS.AES.decrypt(\n        { ciphertext: CryptoJS.enc.Base64.parse(encryptedPayload.data) } as CryptoJS.lib.CipherParams,\n        key,\n        {\n          iv: CryptoJS.enc.Base64.parse(encryptedPayload.iv),\n          mode: CryptoJS.mode.CBC,\n          padding: CryptoJS.pad.Pkcs7,\n        },\n      );\n      const text = decrypted.toString(CryptoJS.enc.Utf8);\n      return text ? (JSON.parse(text) as T) : null;\n    } catch {\n      return null;\n    }\n  };\n\n  const decryptAuthPayload = <T extends Record<string, any>>(\n    payload: T,\n    fields: readonly string[] = [\"roles\", \"permissions\"],\n  ): T => {\n    const decryptedPayload = { ...payload };\n\n    for (const field of fields) {\n      const value = payload[field];\n      if (Array.isArray(value)) continue;\n      decryptedPayload[field as keyof T] = (decrypt(value) ?? []) as T[keyof T];\n    }\n\n    return decryptedPayload;\n  };\n\n  return { encrypt, decrypt, decryptAuthPayload };\n}\n\nexport function createPermissionDecryptor(secret: string) {\n  const { decrypt } = createPermissionCrypto(secret);\n  return (payload: unknown): string[] => {\n    const permissions = decrypt<unknown>(payload);\n    return Array.isArray(permissions) ? permissions : [];\n  };\n}\n","import { configurePermission, getCurrentPermissions } from \"@/core/config\";\r\nimport { hasPermission } from \"@/core/evaluator\";\r\nimport type { GuardOptions, PermissionRoute, PermissionValue } from \"@/types\";\r\nimport type { NavigationGuardNext, RouteLocationNormalized } from \"vue-router\";\r\n\r\nconst MAX_ROUTE_DEPTH = 50;\r\n\r\n/**\r\n * Find a matching node in protectedRoutes for the given target path.\r\n * Matches either by raw concatenated path (parent + child) or by direct\r\n * path equality at any nesting depth.\r\n */\r\nfunction findProtectedRouteMatch(\r\n  routes: PermissionRoute[],\r\n  targetPath: string,\r\n  basePath = \"\",\r\n  depth = 0,\r\n): PermissionRoute | null {\r\n  if (depth > MAX_ROUTE_DEPTH) return null;\r\n  for (const route of routes) {\r\n    const fullPath = basePath + route.path;\r\n    if (fullPath === targetPath || route.path === targetPath) return route;\r\n    if (route.children?.length) {\r\n      const child = findProtectedRouteMatch(\r\n        route.children,\r\n        targetPath,\r\n        fullPath,\r\n        depth + 1,\r\n      );\r\n      if (child) return child;\r\n    }\r\n  }\r\n  return null;\r\n}\r\n\r\n/**\r\n * Global Permission Guard\r\n * ------------------------\r\n * A ready-to-use guard for Vue/Nuxt router.\r\n *\r\n * Example:\r\n * router.beforeEach((to, from, next) => globalGuard(to, from, next, {\r\n *   authRoutes,\r\n *   protectedRoutes,\r\n *   getAuthState: () => authStore.state,\r\n *   loginPath: '/login',\r\n *   homePath: '/'\r\n * }))\r\n */\r\nexport const globalGuard = async (\r\n  to: RouteLocationNormalized,\r\n  from: RouteLocationNormalized,\r\n  next: NavigationGuardNext,\r\n  options: GuardOptions = {},\r\n) => {\r\n  const {\r\n    authRoutes = [],\r\n    protectedRoutes = [] as PermissionRoute[],\r\n    getAuthState,\r\n    loginPath = \"/login\",\r\n    homePath = \"/\",\r\n    onDenied,\r\n    onAllowed,\r\n  } = options;\r\n\r\n  try {\r\n    const authState = getAuthState?.() ?? { isAuthenticated: false };\r\n    const isAuthenticated = authState.isAuthenticated;\r\n\r\n    // Resolve user permissions with full fallback chain.\r\n    // Many consumer projects expose them via authState.user.permissions and\r\n    // never call setPermissions/configurePermission explicitly.\r\n    const userPermissions =\r\n      authState.permissions ??\r\n      authState.user?.permissions ??\r\n      getCurrentPermissions();\r\n\r\n    // If we discovered permissions on the auth payload that the package\r\n    // didn't know about yet, sync them so the directive/composable see them.\r\n    if (\r\n      Array.isArray(userPermissions) &&\r\n      userPermissions.length > 0 &&\r\n      getCurrentPermissions().length === 0\r\n    ) {\r\n      configurePermission(userPermissions);\r\n    }\r\n\r\n    const isAuthRoute = authRoutes.some((r) => r.path === to.path);\r\n\r\n    // Membership in protectedRoutes implies auth + permission requirements,\r\n    // even when the route's meta doesn't set requiresAuth/checkPermission.\r\n    const matchedProtected = findProtectedRouteMatch(protectedRoutes, to.path);\r\n\r\n    const requiresAuth =\r\n      (to.meta?.requiresAuth ?? false) || matchedProtected !== null;\r\n\r\n    const effectivePermissions: PermissionValue | undefined =\r\n      to.meta?.permissions ?? matchedProtected?.meta?.permissions;\r\n\r\n    const checkPermission =\r\n      (to.meta?.checkPermission ?? false) ||\r\n      (matchedProtected !== null && effectivePermissions !== undefined);\r\n\r\n    if (!isAuthenticated && requiresAuth) {\r\n      onDenied?.(to, from);\r\n      return next(loginPath);\r\n    }\r\n\r\n    if (isAuthenticated && isAuthRoute) {\r\n      onAllowed?.(to, from);\r\n      return next(homePath);\r\n    }\r\n\r\n    if (checkPermission && effectivePermissions !== undefined) {\r\n      const allowed = await hasPermission(\r\n        effectivePermissions,\r\n        userPermissions,\r\n      );\r\n      if (!allowed) {\r\n        onDenied?.(to, from);\r\n        const fallback = await findAccessibleRoute(\r\n          protectedRoutes,\r\n          userPermissions,\r\n        );\r\n        return next(fallback || loginPath);\r\n      }\r\n    }\r\n\r\n    onAllowed?.(to, from);\r\n    next();\r\n  } catch (e) {\r\n    console.error(\"[v-permission:globalGuard] Unexpected error:\", e);\r\n    next(loginPath);\r\n  }\r\n};\r\n\r\n/**\r\n * Helper to find the first accessible route from protectedRoutes.\r\n * Includes depth protection against circular/deeply nested routes.\r\n */\r\nasync function findAccessibleRoute(\r\n  routes: PermissionRoute[],\r\n  userPermissions: string[],\r\n  basePath = \"\",\r\n  depth = 0,\r\n): Promise<string | null> {\r\n  if (depth > MAX_ROUTE_DEPTH) {\r\n    console.warn(\"[v-permission:globalGuard] Route nesting exceeds max depth\");\r\n    return null;\r\n  }\r\n\r\n  for (const route of routes) {\r\n    const fullPath = basePath + route.path;\r\n    const requiredPermissions = route.meta?.permissions ?? \"*\";\r\n\r\n    if (await hasPermission(requiredPermissions, userPermissions)) {\r\n      return fullPath;\r\n    }\r\n\r\n    if (route.children?.length) {\r\n      const child = await findAccessibleRoute(\r\n        route.children,\r\n        userPermissions,\r\n        fullPath,\r\n        depth + 1,\r\n      );\r\n      if (child) return child;\r\n    }\r\n  }\r\n  return null;\r\n}\r\n\r\nexport default globalGuard;\r\n","import {\r\n  configurePermission,\r\n  getCurrentPermissions,\r\n  getDecryptHook,\r\n} from \"@/core/config\";\r\nimport { hasPermission } from \"@/core/evaluator\";\r\nimport type { GuardOptions, PermissionRoute, PermissionValue } from \"@/types\";\r\nimport type { NavigationGuardNext, RouteLocationNormalized } from \"vue-router\";\r\n\r\nconst MAX_ROUTE_DEPTH = 50;\r\n\r\nfunction joinPath(base: string, segment: string): string {\r\n  if (!base) return segment;\r\n  if (segment.startsWith(\"/\")) return segment;\r\n  return base.endsWith(\"/\") ? base + segment : base + \"/\" + segment;\r\n}\r\n\r\nfunction findProtectedRouteMatch(\r\n  routes: PermissionRoute[],\r\n  targetPath: string,\r\n  basePath = \"\",\r\n  depth = 0,\r\n): PermissionRoute | null {\r\n  if (depth > MAX_ROUTE_DEPTH) return null;\r\n  for (const route of routes) {\r\n    const fullPath = joinPath(basePath, route.path);\r\n    if (fullPath === targetPath) return route;\r\n    if (route.children?.length) {\r\n      const child = findProtectedRouteMatch(\r\n        route.children,\r\n        targetPath,\r\n        fullPath,\r\n        depth + 1,\r\n      );\r\n      if (child) return child;\r\n    }\r\n  }\r\n  return null;\r\n}\r\n\r\n/**\r\n * createPermissionGuard\r\n * ---------------------\r\n * Generates a dynamic permission guard for any Vue or Nuxt router.\r\n *\r\n * Example:\r\n * router.beforeEach(createPermissionGuard({\r\n *   loginPath: '/login',\r\n *   homePath: '/',\r\n *   onDenied: (to) => console.warn('Denied:', to.path)\r\n * }))\r\n */\r\nexport const createPermissionGuard = (options: GuardOptions = {}) => {\r\n  const {\r\n    authRoutes = [],\r\n    protectedRoutes = [] as PermissionRoute[],\r\n    getAuthState,\r\n    loginPath = \"/login\",\r\n    homePath = \"/\",\r\n    onDenied,\r\n    onAllowed,\r\n  } = options;\r\n\r\n  return async (\r\n    to: RouteLocationNormalized,\r\n    from: RouteLocationNormalized,\r\n    next: NavigationGuardNext,\r\n  ) => {\r\n    try {\r\n      const authState = getAuthState?.() ?? { isAuthenticated: false };\r\n      const isAuthenticated = authState.isAuthenticated;\r\n\r\n      const decryptFn =\r\n        options.decrypt ?? options.transform ?? getDecryptHook();\r\n\r\n      const rawPermissions =\r\n        authState.permissions ??\r\n        authState.user?.permissions ??\r\n        getCurrentPermissions();\r\n\r\n      let userPermissions: string[] = [];\r\n      if (decryptFn && rawPermissions && !Array.isArray(rawPermissions)) {\r\n        const decrypted = await decryptFn(rawPermissions);\r\n        userPermissions = Array.isArray(decrypted) ? decrypted : [];\r\n      } else if (Array.isArray(rawPermissions)) {\r\n        userPermissions = rawPermissions;\r\n      } else {\r\n        userPermissions = getCurrentPermissions();\r\n      }\r\n\r\n      if (\r\n        Array.isArray(userPermissions) &&\r\n        userPermissions.length > 0 &&\r\n        getCurrentPermissions().length === 0\r\n      ) {\r\n        configurePermission(userPermissions, {\r\n          decrypt: decryptFn,\r\n        });\r\n      }\r\n\r\n      const isAuthRoute = authRoutes.some((r) => r.path === to.path);\r\n\r\n      const matchedProtected = findProtectedRouteMatch(\r\n        protectedRoutes,\r\n        to.path,\r\n      );\r\n\r\n      const requiresAuth =\r\n        (to.meta?.requiresAuth ?? false) || matchedProtected !== null;\r\n\r\n      const effectivePermissions: PermissionValue | undefined =\r\n        to.meta?.permissions ?? matchedProtected?.meta?.permissions;\r\n\r\n      const checkPermission =\r\n        (to.meta?.checkPermission ?? false) ||\r\n        (matchedProtected !== null && effectivePermissions !== undefined);\r\n\r\n      if (!isAuthenticated && requiresAuth) {\r\n        onDenied?.(to, from);\r\n        return next(loginPath);\r\n      }\r\n\r\n      if (isAuthenticated && isAuthRoute) {\r\n        onAllowed?.(to, from);\r\n        return next(homePath);\r\n      }\r\n\r\n      if (checkPermission && effectivePermissions !== undefined) {\r\n        const allowed = await hasPermission(\r\n          effectivePermissions,\r\n          userPermissions,\r\n        );\r\n        if (!allowed) {\r\n          onDenied?.(to, from);\r\n\r\n          const fallback = await findAccessibleRoute(\r\n            protectedRoutes,\r\n            userPermissions,\r\n          );\r\n          return next(fallback || loginPath);\r\n        }\r\n      }\r\n\r\n      onAllowed?.(to, from);\r\n      next();\r\n    } catch (e) {\r\n      console.error(\"[v-permission:guard] Unexpected error:\", e);\r\n      next(loginPath);\r\n    }\r\n  };\r\n};\r\n\r\n/**\r\n * Recursively finds a route that the user has permission to access.\r\n * Includes depth protection against circular/deeply nested routes.\r\n */\r\nasync function findAccessibleRoute(\r\n  routes: PermissionRoute[],\r\n  userPermissions: string[],\r\n  basePath = \"\",\r\n  depth = 0,\r\n): Promise<string | null> {\r\n  if (depth > MAX_ROUTE_DEPTH) {\r\n    console.warn(\"[v-permission:guard] Route nesting exceeds max depth\");\r\n    return null;\r\n  }\r\n\r\n  for (const route of routes) {\r\n    const fullPath = basePath + route.path;\r\n    const requiredPermissions = route.meta?.permissions ?? \"*\";\r\n\r\n    if (await hasPermission(requiredPermissions, userPermissions)) {\r\n      return fullPath;\r\n    }\r\n\r\n    if (route.children?.length) {\r\n      const child = await findAccessibleRoute(\r\n        route.children,\r\n        userPermissions,\r\n        fullPath,\r\n        depth + 1,\r\n      );\r\n      if (child) return child;\r\n    }\r\n  }\r\n  return null;\r\n}\r\n","import { clearPermissionCache } from \"@/core/cache\";\r\nimport {\r\n  configurePermission,\r\n  getCurrentPermissions,\r\n  getReactivePermissions,\r\n} from \"@/core/config\";\r\nimport { hasPermission } from \"@/core/evaluator\";\r\nimport type { PermissionValue } from \"@/types\";\r\nimport {\r\n  getPermissionsFromStorage,\r\n  savePermissionsToStorage,\r\n} from \"@/utils/storage\";\r\nimport { computed } from \"vue\";\r\n\r\n/**\r\n * usePermission Composable\r\n * Reactive + Async + Cached Permission Checker\r\n *\r\n * The returned `permissions` reflects the global reactive state, so any call\r\n * to `configurePermission` or `setPermissions` (from anywhere in the app)\r\n * will be observed automatically.\r\n */\r\nexport function usePermission() {\r\n  // Bind to the global reactive permissions ref. This way the composable\r\n  // always reflects the current state, even if it was called at module\r\n  // top level (a pattern some consumers rely on).\r\n  const permissionsRef = getReactivePermissions();\r\n\r\n  // If the global ref is empty but we have a persisted snapshot in storage,\r\n  // hydrate the global state once. This lets newly-mounted apps pick up\r\n  // permissions saved during the previous session without an explicit call.\r\n  if (\r\n    (!permissionsRef.value || permissionsRef.value.length === 0) &&\r\n    getCurrentPermissions().length === 0\r\n  ) {\r\n    const stored = getPermissionsFromStorage();\r\n    if (Array.isArray(stored) && stored.length > 0) {\r\n      // Don't re-persist (storage already has it); just sync runtime state.\r\n      configurePermission(stored, { persist: false });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * can(rule)\r\n   * Async permission evaluator\r\n   */\r\n  const can = async (rule: PermissionValue) => {\r\n    return await hasPermission(rule, permissionsRef.value);\r\n  };\r\n\r\n  /**\r\n   * canSync(rule)\r\n   * Instant local check — simplified fallback\r\n   */\r\n  const canSync = (rule: PermissionValue) => {\r\n    const current = permissionsRef.value;\r\n    if (rule === \"*\") return true;\r\n    if (typeof rule === \"string\") return current.includes(rule);\r\n    if (Array.isArray(rule)) {\r\n      if (rule.includes(\"*\")) return true;\r\n      return rule.some((r) => current.includes(r));\r\n    }\r\n    if (typeof rule === \"object\" && rule.permissions && rule.mode) {\r\n      const { permissions: p, mode } = rule;\r\n      if (!Array.isArray(p) || p.length === 0) return false;\r\n      if (p.includes(\"*\")) return true;\r\n      if (mode === \"and\") return p.every((v) => current.includes(v));\r\n      if (mode === \"or\") return p.some((v) => current.includes(v));\r\n      if (mode === \"not\") return !p.some((v) => current.includes(v));\r\n      if (mode === \"startWith\")\r\n        return p.some((pat) => current.some((u) => u.startsWith(pat)));\r\n      if (mode === \"endWith\")\r\n        return p.some((pat) => current.some((u) => u.endsWith(pat)));\r\n      if (mode === \"regex\")\r\n        return p.some((pat) => {\r\n          try {\r\n            const r = new RegExp(pat);\r\n            return current.some((u) => r.test(u));\r\n          } catch {\r\n            return false;\r\n          }\r\n        });\r\n    }\r\n    return false;\r\n  };\r\n\r\n  /**\r\n   * refresh()\r\n   * Clear cache and re-read the current permissions from storage so any\r\n   * out-of-band updates (e.g., another tab or a direct storage write) are\r\n   * picked up. If storage is empty, leaves the current global state alone.\r\n   */\r\n  const refresh = () => {\r\n    clearPermissionCache();\r\n    const stored = getPermissionsFromStorage();\r\n    if (Array.isArray(stored) && stored.length > 0) {\r\n      configurePermission(stored, { persist: false });\r\n    }\r\n  };\r\n\r\n  /**\r\n   * setPermissions()\r\n   */\r\n  const setPermissions = (newPerms: string[]) => {\r\n    if (!Array.isArray(newPerms)) {\r\n      console.error(\"[v-permission] Permissions must be an array\");\r\n      return;\r\n    }\r\n    clearPermissionCache();\r\n    // configurePermission will update the reactive ref AND persist to storage\r\n    // (persist defaults to true).\r\n    configurePermission(newPerms);\r\n    savePermissionsToStorage(newPerms);\r\n  };\r\n\r\n  /**\r\n   * hasAll()\r\n   */\r\n  const hasAll = async (perms: string[]) => {\r\n    // Empty array means no requirements, so always true\r\n    if (!Array.isArray(perms) || perms.length === 0) return true;\r\n    return await can({ permissions: perms, mode: \"and\" });\r\n  };\r\n\r\n  /**\r\n   * hasAny()\r\n   */\r\n  const hasAny = async (perms: string[]) => {\r\n    // Empty array or non-array should return false\r\n    if (!Array.isArray(perms) || perms.length === 0) return false;\r\n    return await can({ permissions: perms, mode: \"or\" });\r\n  };\r\n\r\n  return {\r\n    permissions: computed(() => permissionsRef.value),\r\n    can,\r\n    hasPermission: can, // Alias for can() — used in docs & templates\r\n    canSync,\r\n    refresh,\r\n    setPermissions,\r\n    hasAll,\r\n    hasAny,\r\n  };\r\n}\r\n"],"names":["normalizeSecret","rawSecret","secret","createKey","key","CryptoJS","parseEncryptedPayload","payload","candidate","createPermissionCrypto","encrypt","value","iv","encrypted","decrypt","encryptedPayload","text","fields","decryptedPayload","field","createPermissionDecryptor","permissions","MAX_ROUTE_DEPTH","findProtectedRouteMatch","routes","targetPath","basePath","depth","route","fullPath","_a","child","globalGuard","to","from","next","options","authRoutes","protectedRoutes","getAuthState","loginPath","homePath","onDenied","onAllowed","authState","isAuthenticated","userPermissions","getCurrentPermissions","configurePermission","isAuthRoute","r","matchedProtected","requiresAuth","_b","effectivePermissions","_c","_d","checkPermission","_e","hasPermission","fallback","findAccessibleRoute","e","requiredPermissions","joinPath","base","segment","createPermissionGuard","decryptFn","getDecryptHook","rawPermissions","decrypted","usePermission","permissionsRef","getReactivePermissions","stored","getPermissionsFromStorage","can","rule","canSync","current","p","mode","v","pat","u","refresh","clearPermissionCache","setPermissions","newPerms","savePermissionsToStorage","hasAll","perms","hasAny","computed"],"mappings":"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"}