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
JavaScript
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