Skip to content

Permissions

@mongez/user ships a minimal permissions model: store an object, check a dot-notation path for a truthy value.

API

user.setPermissions(obj); // replaces the permissions object
user.can(path); // boolean — truthy value at the path

Returns true only when get(permissions, path) produces a truthy value (true, 1, "yes", a non-empty array, …). Any falsy value or a missing key returns false.

Shape examples

The library is shape-agnostic — pick what matches your backend. Some shapes that work:

Flat dotted keys → booleans

user.setPermissions({
"posts.create": true,
"posts.delete": false,
"admin.panel": true,
});
user.can("posts.create"); // true
user.can("posts.delete"); // false
user.can("posts.archive"); // false (missing)

Nested objects → booleans

user.setPermissions({
posts: { create: true, delete: false },
admin: { panel: true },
});
user.can("posts.create"); // true
user.can("admin.panel"); // true

Role names → truthy strings

user.setPermissions({
posts: { create: "editor", delete: "admin" },
});
user.can("posts.create"); // true ("editor" is truthy)

This works but can() only tells you “yes/no” — it doesn’t expose the role string. Read it directly via the underlying object if you need it:

import { get } from "@mongez/reinforcements";
const role = get(user["permissions"], "posts.create");

…though permissions is protected, so you’d need to expose it via a method on your subclass.

Replace, not merge

user.setPermissions({ a: true });
user.setPermissions({ b: true }); // a is GONE now
user.can("a"); // false
user.can("b"); // true

If you want merge semantics, do it yourself before calling setPermissions.

Persistence

setPermissions does NOT write to the cache driver. Permissions are runtime-only — re-set them after each boot() if you need them across sessions. Typical flow: fetch them after login, then call setPermissions(response.permissions).

You can also store them inside userData (via set("permissions", obj)) so they ride along with the cache driver, then re-apply on boot:

class AppUser extends BaseUser {
protected cacheDriver = myDriver;
protected enableEvents = true;
public override boot() {
super.boot();
const persisted = this.get("permissions");
if (persisted) this.setPermissions(persisted);
return this;
}
}
// On login:
user.login({ ...userData, permissions: response.permissions });
user.setPermissions(response.permissions);

Defining permission types

import type { Role, PermissionGroup } from "@mongez/user";
const groups: PermissionGroup[] = [
{
text: "Posts",
name: "posts",
roles: [
{ text: "Create", name: "create" },
{ text: "Delete", name: "delete" },
],
},
];

These types are exported for callers wiring permission UI. setPermissions itself accepts any object — the types are not enforced internally.