packages
usePermissions

usePermissions

Layer user permissions into your application with hooks

Usage

JavaScript

import { PermissionsProvider, usePermissions } from '@hookit/permissions';
 
const admin = {
  DoThis: true,
  DoThat: true,
  GetThis: true,
  GetThat: true,
};
 
const normal = {
  DoThis: true,
  DoThat: ({ firstArg, secondArg }) => firstArg === secondArg,
  GetThis: false,
  GetThat: ({ firstArg, secondArg }) => firstArg === secondArg,
};
 
const rules = {
  admin,
  normal,
};
 
// Set up PermissionsProvider to pass rules through context
export const App = () => {
  return (
    <PermissionsProvider rules={rules}>
      <Component role='admin' firstArg={1} secondArg={1} />
    </PermissionsProvider>
  );
};
 
// Use permissions hook to check if a user has permissions based on roles
const Component = ({ role, firstArg, secondArg }) => {
  const { canAccess } = usePermissions(role);
 
  const canDoThis = canAccess('DoThis', { firstArg, secondArg });
 
  return (
    <>
      <h3>Current User Role: {role}</h3>
      <p>canDoThis: {canDoThis ? '✅' : '🚫'}</p>
    </>
  );
};

TypeScript

import { PermissionsProvider, TPermissions, TRules, usePermissions } from '@hookit/permissions';
 
type Permissions = 'DoThis' | 'DoThat' | 'GetThis' | 'GetThat';
type Roles = 'admin' | 'normal' | 'free';
 
// Use types  to help construct permissions
const admin: TPermissions<Permissions> = {
  DoThis: true,
  DoThat: true,
  GetThis: true,
  GetThat: true,
};
 
type ARGS = { firstArg: number; secondArg: number };
 
const normal: TPermissions<Permissions> = {
  DoThis: true,
  DoThat: ({ firstArg, secondArg }: ARGS) => firstArg === secondArg,
  GetThis: false,
  GetThat: ({ firstArg, secondArg }: ARGS) => firstArg === secondArg,
};
 
// Use types  to help construct rules
const rules: TRules<Permissions, Roles> = {
  admin,
  normal,
};
 
// Set up PermissionsProvider to pass rules through context
export const App: React.FC = () => {
  return (
    <PermissionsProvider rules={rules}>
      <Component role='admin' />
    </PermissionsProvider>
  );
};
 
// Use permissions hook to check if a user has permissions based on roles
const Component: React.FC<{
  role: Roles;
  firstArg: number;
  secondArg: number;
}> = ({ role, firstArg, secondArg }) => {
  const { canAccess } = usePermissions<Permissions, Roles>(role);
 
  const canDoThis = canAccess<ARGS>('DoThis', { firstArg, secondArg });
 
  return (
    <>
      <h3>Current User Role: {role}</h3>
      <p>canDoThis: {canDoThis ? '✅' : '🚫'}</p>
    </>
  );
};

You can alternatively use enums instead of unions to help construct your types. Be aware that the pattern for typing components changes:

// type Permissions = 'DoThis' | 'DoThat' | 'GetThis' | 'GetThat';
// type Roles = 'admin' | 'normal' | 'free';
 
enum Permissions {
  DoThis = 'DoThis',
  DoThat = 'DoThat',
  GetThis = 'GetThis',
  GetThat = 'GetThat',
}
enum Roles {
  admin = 'admin',
  normal = 'normal',
  free = 'free',
}
 
//...
 
const { canAccess } = usePermissions<Permissions, Roles>(role); // role must also be a computed from `Roles`
 
const Component: React.FC<{
  role: Roles;
  firstArg: number;
  secondArg: number;
}> = ({ role, firstArg, secondArg }) => {
  const canDoThis = canAccess<ARGS>(Permissions.DoThis, {
    firstArg,
    secondArg,
  });
 
  //...
};

Arguments

PermissionsProvider

NameTypeRequired?
rulesTRules<Permissions, Roles>

usePermissions

NameTypeRequired?
roleRoles | string

canAccess() from usePermissions

NameTypeRequired?
permissionPermissions | string
argsany

Returns

PermissionsProvider

Just puts your rules into context for usePermissions to access.

usePermissions

NameDescriptionReturn Type
canAccessfunction that returns permissions from contextboolean