@canxjs/dominion
v1.0.0
Published
CanxJS Dominion - Advanced Roles and Permissions
Maintainers
Readme
@canxjs/dominion
✨ Features
- 👥 Role Management - Assign multiple roles to users
- 🔑 Direct Permissions - Grant permissions directly to users
- 🎭 Role Permissions - Assign permissions to roles
- 🔄 Sync Operations - Easily sync roles and permissions
- 🛡️ Guard Support - Multiple authentication guards
📦 Installation
npm install @canxjs/dominion
# or
bun add @canxjs/dominion🚀 Quick Start
1. Register the Service Provider
// src/providers.ts
import { DominionServiceProvider } from "@canxjs/dominion";
export const providers = [
// ... other providers
DominionServiceProvider,
];2. Run the Install Command
node canx dominion:install
node canx migrate3. Add Mixin to User Model
import { Model } from "canxjs";
import { HasRoles } from "@canxjs/dominion";
class User extends HasRoles(Model) {
static tableName = "users";
id!: number;
email!: string;
// ... other fields
}📖 Usage
Creating Roles & Permissions
import { Role, Permission } from "@canxjs/dominion";
// Create permissions
await Permission.create({ name: "create posts", guard_name: "web" });
await Permission.create({ name: "edit posts", guard_name: "web" });
await Permission.create({ name: "delete posts", guard_name: "web" });
// Create a role
const writerRole = await Role.create({ name: "writer", guard_name: "web" });
// Assign permissions to role
await writerRole.permissions().attach([1, 2]); // attach by IDsAssigning Roles to Users
const user = await User.find(1);
// Assign a single role
await user.assignRole("writer");
// Assign multiple roles
await user.assignRole("writer", "editor");
// Assign by Role instance
const adminRole = await Role.where("name", "admin").first();
await user.assignRole(adminRole);Checking Roles
// Check if user has a role
if (await user.hasRole("writer")) {
// User is a writer
}
// Get all user roles
const roles = await user.roles().get();Direct Permissions
// Give permissions directly to user (bypassing roles)
await user.givePermissionTo("publish posts");
// Revoke a permission
await user.revokePermissionTo("publish posts");
// Get all direct permissions
const permissions = await user.permissions().get();Checking Permissions
// Check permission (checks both direct AND role-based)
if (await user.hasPermissionTo("edit posts")) {
// User can edit posts
}
// This works with permission names or Permission instances
const editPerm = await Permission.where("name", "edit posts").first();
if (await user.hasPermissionTo(editPerm)) {
// User can edit posts
}Syncing Roles
// Replace all current roles with new ones
await user.syncRoles("admin", "manager");
// Remove a role
await user.removeRole("writer");🔧 How It Works
Database Schema
Dominion creates the following tables:
roles
| Column | Type | Description |
|--------|------|-------------|
| id | integer | Primary key |
| name | string | Role name (e.g., "admin") |
| guard_name | string | Auth guard (default: "web") |
permissions
| Column | Type | Description |
|--------|------|-------------|
| id | integer | Primary key |
| name | string | Permission name (e.g., "edit posts") |
| guard_name | string | Auth guard (default: "web") |
role_has_permissions (pivot)
| Column | Type | Description |
|--------|------|-------------|
| role_id | integer | Foreign key to roles |
| permission_id | integer | Foreign key to permissions |
model_has_roles (pivot)
| Column | Type | Description |
|--------|------|-------------|
| role_id | integer | Foreign key to roles |
| model_type | string | Model class name |
| model_id | integer | Model primary key |
model_has_permissions (pivot)
| Column | Type | Description |
|--------|------|-------------|
| permission_id | integer | Foreign key to permissions |
| model_type | string | Model class name |
| model_id | integer | Model primary key |
Permission Resolution
When checking hasPermissionTo():
- First, check direct permissions on the user
- Then, check permissions through each assigned role
- Returns
trueif found in either
User
├── Direct Permissions (model_has_permissions)
│ └── "publish posts"
└── Roles (model_has_roles)
├── "writer" → Permissions: ["create posts", "edit posts"]
└── "editor" → Permissions: ["edit posts", "delete posts"]📚 API Reference
HasRoles Mixin
| Method | Description |
| ------------------------------ | ----------------------------------- |
| assignRole(...roles) | Assign one or more roles |
| removeRole(...roles) | Remove one or more roles |
| syncRoles(...roles) | Replace all roles |
| hasRole(role) | Check if user has a role |
| roles() | Get roles relationship |
| givePermissionTo(...perms) | Grant direct permissions |
| revokePermissionTo(...perms) | Revoke direct permissions |
| hasPermissionTo(perm) | Check if user has permission |
| permissions() | Get direct permissions relationship |
Role Model
| Method | Description |
| --------------- | ----------------------------------- |
| permissions() | Get role's permissions relationship |
Permission Model
Standard Eloquent model with name and guard_name fields.
📄 License
MIT © CanxJS Team
