Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/inshadowin/react-permissions

Lightweight package that resolves permissions in your app
https://github.com/inshadowin/react-permissions

permissions permissions-dynamic react reactjs

Last synced: 2 months ago
JSON representation

Lightweight package that resolves permissions in your app

Awesome Lists containing this project

README

        

# react-permissions

Lightweight package that resolves permissions in your app

## How to use

Wrap your App in `PermissionsProvider`

```jsx
const Main = () => {
return {/* your app code */};
};
```

Provide `initialPermissions?: CheckResult` and/or `onCheckPermissions?: OnCheckPermissionsType`
If you have all permissions somewhere, and you don't need dynamic checks - use only `initialPermissions`
If permissions are controled by you - use `permissions` prop

```jsx
type CheckResult = {
action: string,
allowed?: boolean,
}[];

type OnCheckPermissionsType = (
actions: string[]
) => Promise | CheckResult;

const exampleInitialPermissions = [
{ action: 'can_view_transactions', allowed: true },
{ action: 'can_edit_people', allowed: false },
];

const exampleCheckPermissions = (actions: string[]) => {
return [
{ action: 'this_is_allowed', allowed: true },
{ action: 'denied_this_is', allowed: false },
{ action: 'undefined_is_allowed' },
];
};

return (

// children

);
```

It's recommended to specify union-type for your components/utilities
You can do it like this

```tsx
import {
PermissionCheck as LibPermissionCheck,
PermissionsProvider as LibPermissionsProvider,
} from 'react-permissions-dynamic';

import type {
PermissionCheckProps as LibPermissionCheckProps,
PermissionsProviderProps as LibPermissionsProviderProps,
} from 'react-permissions-dynamic';

type MyPermission = 'can_view_files' | 'can_edit_files';

type PermissionCheckProps = LibPermissionCheckProps;
type PermissionsProviderProps = LibPermissionsProviderProps;

const PermissionCheck = LibPermissionCheck as React.FC;
const PermissionsProvider =
LibPermissionsProvider as React.FC;

export { PermissionCheck, PermissionsProvider };
```

In the code itself use `PermissionCheck` component

```jsx
// Base usage:
return (



);

// Two or more permissions at the same time:
return (



);

// Provide Fallback for denied access:
return (



);

// Provide Loading if checks are dynamic:
return (
} action="can_view_files">


);

// Provide onDeny if you want to do something on permission deny
return (
{
logger.info(`Action [${action}] got denied`);
redirectUser('/');
}}
>


);

// Provide custom logic for permissions
return (
{
if (
allowed.includes('can_view_files') &&
allowed.includes('can_view_system_files')
) {
return true;
}

return !denied.includes('has_full_access');
}}
>


);
```

## Utilities

### PermissionCheck

This component allows you to hide content based on permissions

```jsx
type PermissionCheckProps = {
// this action/actions will be checked upon
// if it's allowed - we will show content
action: string | string[],

// content that must be shown if action is allowed
children: React.ReactNode,

// content that must be shown if action is not allowed
// default = null
fallback?: React.ReactNode,

// content that must be shown while we check if action is allowed
// default = null
loading?: React.ReactNode,

// event when action is denied
// fire alerts, write logs or redirects - do anything
onDenied?: (action: string) => void,

// if you need to implement custom check
// by default we need to have all actions allowed
isAllowed?: (allowedActions: string[], deniedActions: string[]) => boolean,
};

return Secure Content;
```

### useCheckPermission

```tsx
type ActionStatusType = {
// return action just in case you need it
action: T;
// if action is checked and allowed - returns true
allowed: boolean;
// if action is checked - returns true. if check is in progress - returns false
checked: boolean;
};

type UseCheckPermissionType = (
action: T
) => ActionStatusType;

// Example:
const Component = () => {
const { allowed, checked } = useCheckPermission('can_view_files');

return allowed ? : null;
};
```

### useCheckPermissions

```tsx
type UseCheckPermissionsType = (
actions: T[],
onCheck?: (status: ActionStatusType) => void
) => ActionStatusType[];

// Same as useCheckPermission, but you get array of results
// Also has onCheck callback, for single permission check

// Example:
const Component = () => {
const handleOnCheck = status => {
// actions here are always "checked", so no need to have `status.checked === true` condition
if (status.action === 'is_admin' && !status.allowed) {
return redirect('/404');
}
};
const results = useCheckPermissions(
['can_upload_files', 'is_admin'],
handleOnCheck
);

return results.some(s => s.action === 'can_upload_files' && s.allowed) ? (

) : null;
};
```