Permissions Roles, permissions, and policies for NetPress
NetPressv0.1.7 Permissionsv0.2.3 Docsv0.2.2
Overview Installation Policies Auth Guard
Core Concepts

Traits

Subject models gain role and permission behaviour through mixin functions. This mirrors Spatie's HasRoles and HasPermissions traits, but implemented with JavaScript's prototype chain.

Authorizable

The most common entry point is the Authorizable(BaseClass) function. It composes HasRoles and HasPermissions into a fresh subclass.

import { BaseModel } from '@admicaa/netpress';
import { Authorizable } from '@admicaa/netpress-permissions';

class User extends Authorizable(BaseModel) {
  static table = 'users';
}

User now has roles(), permissions(), assignRole(), can(), and all the helpers documented in Roles and Permissions.

Applying To An Existing Class

If you can't extend a wrapping class (for example, the class already extends something custom), use applyAuthorizable to splice the behaviour onto an existing prototype:

import { applyAuthorizable } from '@admicaa/netpress-permissions';

class Admin extends BaseModel {
  static table = 'admins';
}

applyAuthorizable(Admin);

applyAuthorizable copies the descriptors from both HasRoles and HasPermissions onto the class prototype. You can call it as many times as you like — duplicate descriptors are overwritten without error.

Splitting The Traits

If you only need roles or only need direct permissions, import each mixin individually:

import { HasRoles, HasPermissions } from '@admicaa/netpress-permissions';

class User extends HasRoles(BaseModel) { /* ... */ }
class ApiClient extends HasPermissions(BaseModel) { /* ... */ }

Note that user.hasPermissionTo('x') will always short-circuit through the role chain. If you apply HasPermissions without HasRoles, the package gracefully reports an empty role list.

Methods Added By HasRoles

  • roles() relation
  • getRoles(), getRoleNames()
  • assignRole(...roles), removeRole(...roles), syncRoles(...roles)
  • hasRole(role), hasAnyRole(...roles), hasAllRoles(...roles)

Methods Added By HasPermissions

  • permissions() relation
  • getDirectPermissions(), getPermissionsViaRoles(), getAllPermissions()
  • givePermissionTo(...permissions), revokePermissionTo(...permissions), syncPermissions(...permissions)
  • hasDirectPermission(permission), hasPermissionTo(permission)
  • hasAnyPermission(...permissions), hasAllPermissions(...permissions)
  • can(ability, resource = null, options = {}) and cannot(...)

can delegates to NetPress core authorization so registered policies and permission-aware models are honoured automatically.

Morph Map

To support inverse queries (Permission.holders(User), Role.assignees(Admin)), register your subject classes with the morph map once at boot:

import { BaseModel } from '@admicaa/netpress';

BaseModel.registerMorphMap({
  user: User,
  admin: Admin,
});

The Authorizable mixins use morphToMany and morphedByMany, so the registry is required before you run any pivot queries against the package tables. Without it the package cannot resolve polymorphic identifiers.