UNPKG

vue-nuxt-permission

Version:

A unified permission system for Vue 3 and Nuxt 3 / Nuxt 4 with directives, guards, and async support.

323 lines (322 loc) 9.35 kB
import { g as R, c as S, h as q, a as F, b as N, d as U, e as O, s as $ } from "./plugin-BUIUV0Ey.js"; import { P as nr, q as ir, j as or, l as ar, i as cr, p as ur, r as lr, n as fr, k as dr, f as hr, m as mr, o as yr, v as pr } from "./plugin-BUIUV0Ey.js"; import h from "crypto-js"; import { computed as z } from "vue"; /*! vue-nuxt-permission v2.2.1 | (c) 2026 Kerolos Zakaria | MIT License */ function X(e) { if (!e || typeof e != "string") throw new Error("A crypto secret is required"); const s = e.trim(); return s.startsWith('"') && s.endsWith('"') ? s.slice(1, -1) : s; } function D(e) { const s = h.enc.Utf8.parse(X(e)); return s.sigBytes = 32, s.words.length = 8, s; } function j(e) { if (e && typeof e == "object") { const s = e; if (typeof s.iv == "string" && typeof s.data == "string") return s; } if (typeof e == "string") try { return j(JSON.parse(e)); } catch { return null; } return null; } function K(e) { const s = D(e), c = (i) => { const t = h.lib.WordArray.random(16), r = h.AES.encrypt(JSON.stringify(i), s, { iv: t, mode: h.mode.CBC, padding: h.pad.Pkcs7 }); return { iv: h.enc.Base64.stringify(t), data: h.enc.Base64.stringify(r.ciphertext) }; }, a = (i) => { try { const t = j(i); if (!t) return null; const o = h.AES.decrypt( { ciphertext: h.enc.Base64.parse(t.data) }, s, { iv: h.enc.Base64.parse(t.iv), mode: h.mode.CBC, padding: h.pad.Pkcs7 } ).toString(h.enc.Utf8); return o ? JSON.parse(o) : null; } catch { return null; } }; return { encrypt: c, decrypt: a, decryptAuthPayload: (i, t = ["roles", "permissions"]) => { const r = { ...i }; for (const o of t) { const n = i[o]; Array.isArray(n) || (r[o] = a(n) ?? []); } return r; } }; } function Y(e) { const { decrypt: s } = K(e); return (c) => { const a = s(c); return Array.isArray(a) ? a : []; }; } const x = 50; function M(e, s, c = "", a = 0) { var u; if (a > x) return null; for (const i of e) { const t = c + i.path; if (t === s || i.path === s) return i; if ((u = i.children) != null && u.length) { const r = M( i.children, s, t, a + 1 ); if (r) return r; } } return null; } const Z = async (e, s, c, a = {}) => { var f, m, P, k, w; const { authRoutes: u = [], protectedRoutes: i = [], getAuthState: t, loginPath: r = "/login", homePath: o = "/", onDenied: n, onAllowed: l } = a; try { const y = (t == null ? void 0 : t()) ?? { isAuthenticated: !1 }, b = y.isAuthenticated, p = y.permissions ?? ((f = y.user) == null ? void 0 : f.permissions) ?? R(); Array.isArray(p) && p.length > 0 && R().length === 0 && S(p); const A = u.some((v) => v.path === e.path), d = M(i, e.path), E = (((m = e.meta) == null ? void 0 : m.requiresAuth) ?? !1) || d !== null, g = ((P = e.meta) == null ? void 0 : P.permissions) ?? ((k = d == null ? void 0 : d.meta) == null ? void 0 : k.permissions), W = (((w = e.meta) == null ? void 0 : w.checkPermission) ?? !1) || d !== null && g !== void 0; if (!b && E) return n == null || n(e, s), c(r); if (b && A) return l == null || l(e, s), c(o); if (W && g !== void 0 && !await q( g, p )) { n == null || n(e, s); const B = await T( i, p ); return c(B || r); } l == null || l(e, s), c(); } catch (y) { console.error("[v-permission:globalGuard] Unexpected error:", y), c(r); } }; async function T(e, s, c = "", a = 0) { var u, i; if (a > x) return console.warn("[v-permission:globalGuard] Route nesting exceeds max depth"), null; for (const t of e) { const r = c + t.path, o = ((u = t.meta) == null ? void 0 : u.permissions) ?? "*"; if (await q(o, s)) return r; if ((i = t.children) != null && i.length) { const n = await T( t.children, s, r, a + 1 ); if (n) return n; } } return null; } const G = 50; function I(e, s) { return !e || s.startsWith("/") ? s : e.endsWith("/") ? e + s : e + "/" + s; } function H(e, s, c = "", a = 0) { var u; if (a > G) return null; for (const i of e) { const t = I(c, i.path); if (t === s) return i; if ((u = i.children) != null && u.length) { const r = H( i.children, s, t, a + 1 ); if (r) return r; } } return null; } const rr = (e = {}) => { const { authRoutes: s = [], protectedRoutes: c = [], getAuthState: a, loginPath: u = "/login", homePath: i = "/", onDenied: t, onAllowed: r } = e; return async (o, n, l) => { var f, m, P, k, w; try { const y = (a == null ? void 0 : a()) ?? { isAuthenticated: !1 }, b = y.isAuthenticated, p = e.decrypt ?? e.transform ?? F(), A = y.permissions ?? ((f = y.user) == null ? void 0 : f.permissions) ?? R(); let d = []; if (p && A && !Array.isArray(A)) { const C = await p(A); d = Array.isArray(C) ? C : []; } else Array.isArray(A) ? d = A : d = R(); Array.isArray(d) && d.length > 0 && R().length === 0 && S(d, { decrypt: p }); const E = s.some((C) => C.path === o.path), g = H( c, o.path ), W = (((m = o.meta) == null ? void 0 : m.requiresAuth) ?? !1) || g !== null, v = ((P = o.meta) == null ? void 0 : P.permissions) ?? ((k = g == null ? void 0 : g.meta) == null ? void 0 : k.permissions), B = (((w = o.meta) == null ? void 0 : w.checkPermission) ?? !1) || g !== null && v !== void 0; if (!b && W) return t == null || t(o, n), l(u); if (b && E) return r == null || r(o, n), l(i); if (B && v !== void 0 && !await q( v, d )) { t == null || t(o, n); const _ = await J( c, d ); return l(_ || u); } r == null || r(o, n), l(); } catch (y) { console.error("[v-permission:guard] Unexpected error:", y), l(u); } }; }; async function J(e, s, c = "", a = 0) { var u, i; if (a > G) return console.warn("[v-permission:guard] Route nesting exceeds max depth"), null; for (const t of e) { const r = c + t.path, o = ((u = t.meta) == null ? void 0 : u.permissions) ?? "*"; if (await q(o, s)) return r; if ((i = t.children) != null && i.length) { const n = await J( t.children, s, r, a + 1 ); if (n) return n; } } return null; } function er() { const e = N(); if ((!e.value || e.value.length === 0) && R().length === 0) { const r = U(); Array.isArray(r) && r.length > 0 && S(r, { persist: !1 }); } const s = async (r) => await q(r, e.value), c = (r) => { const o = e.value; if (r === "*") return !0; if (typeof r == "string") return o.includes(r); if (Array.isArray(r)) return r.includes("*") ? !0 : r.some((n) => o.includes(n)); if (typeof r == "object" && r.permissions && r.mode) { const { permissions: n, mode: l } = r; if (!Array.isArray(n) || n.length === 0) return !1; if (n.includes("*")) return !0; if (l === "and") return n.every((f) => o.includes(f)); if (l === "or") return n.some((f) => o.includes(f)); if (l === "not") return !n.some((f) => o.includes(f)); if (l === "startWith") return n.some((f) => o.some((m) => m.startsWith(f))); if (l === "endWith") return n.some((f) => o.some((m) => m.endsWith(f))); if (l === "regex") return n.some((f) => { try { const m = new RegExp(f); return o.some((P) => m.test(P)); } catch { return !1; } }); } return !1; }, a = () => { O(); const r = U(); Array.isArray(r) && r.length > 0 && S(r, { persist: !1 }); }, u = (r) => { if (!Array.isArray(r)) { console.error("[v-permission] Permissions must be an array"); return; } O(), S(r), $(r); }, i = async (r) => !Array.isArray(r) || r.length === 0 ? !0 : await s({ permissions: r, mode: "and" }), t = async (r) => !Array.isArray(r) || r.length === 0 ? !1 : await s({ permissions: r, mode: "or" }); return { permissions: z(() => e.value), can: s, hasPermission: s, // Alias for can() — used in docs & templates canSync: c, refresh: a, setPermissions: u, hasAll: i, hasAny: t }; } export { nr as PermissionPlugin, O as clearPermissionCache, ir as clearPermissionsFromStorage, S as configurePermission, K as createPermissionCrypto, Y as createPermissionDecryptor, rr as createPermissionGuard, or as getCachedPermission, R as getCurrentPermissions, F as getDecryptHook, U as getPermissionsFromStorage, Z as globalGuard, q as hasPermission, ar as invalidateCache, cr as isDevMode, ur as isPermissionObject, lr as logDebug, fr as normalizePermissions, $ as savePermissionsToStorage, dr as setCachedPermission, hr as setDecryptHook, mr as sortUniq, yr as stableStringify, er as usePermission, pr as vPermission }; //# sourceMappingURL=index.mjs.map